-
Notifications
You must be signed in to change notification settings - Fork 506
Require minimally-encoded features in BOLT 11 invoices #1245
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
Require minimally-encoded features in BOLT 11 invoices #1245
Conversation
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 was just playing with this yesterday lightningdevkit/rust-lightning#3703
I agree that making the invoice valid required a bunch of tricky code that does not make sense to have.
ACK e2e81aa
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.
Concept ACK, I just need to add the test vector to eclair
and will properly ACK.
Ack. Shall we similarly make the other "SHOULD use minimal encoding" into MUST? |
7b9451c
to
8c712d6
Compare
When decoding BOLT 11 invoices, LDK has always read them into fields, parsing what it can. When parsing features, CLTV deltas, and expiry times, this loses the information on the number of field elements which were used to encode the features in the invoice itself. When we then go to calculate a hash of the invoice for signature validation/key recovery, we go re-serialize the invoice. At this point, any excess field elements used to encode fields will be lost and the invoice's hash will be different from what the original encoder intended. Luckily, this doesn't appear to have ever happened in practice. This was, in fact, only found by @erickcestari, @brunoerg, and @morehouse when doing differential fuzzing. Because this hasn't happened and it breaks a straightforward way to handle BOLT 11 parsing, there's no reason to retain it, so instead here we simply forbid non-minimally-encoded features in BOLT 11 invoices. See lightningdevkit/rust-lightning#3693 for the specific example generated by fuzzing.
@t-bast mentioned on the call that they've run into non-largest multipliers in BOLT 11 invoices in the wild and as such we can't reject them.
8c712d6
to
4042520
Compare
Clarified what the minimal length thing means as requested at the meeting.
Oops, indeed, done. Note that for any of the three LDK would have failed to pay the invoice (invalid signature or wrong pubkey from recovery) and we haven't received any reports of it. Sadly, I did not apply this to the amount because @t-bast indicated at the meeting that they've seen non-minimal ones. |
lightning/bolts#1245 highlights that invoice writers must minimally encode Bolt11 features (and other fields). We were already correctly doing that, but tests were lacking. lightning/bolts#1242 added a test vector for invoices without payment secrets, which we're now verifying.
lightning/bolts#1245 highlights that invoice writers must minimally encode Bolt11 features (and other fields). We were already correctly doing that, but tests were lacking. lightning/bolts#1242 added a test vector for invoices without payment secrets, which we're now verifying.
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.
ACK, verified that eclair
and lightning-kmp
minimally-encode all of these.
lightning/bolts#1245 highlights that invoice writers must minimally encode Bolt11 features (and other fields). We were already correctly doing that, but tests were lacking. lightning/bolts#1242 added a test vector for invoices without payment secrets, which we're now verifying.
lightning/bolts#1245 highlights that invoice writers must minimally encode Bolt11 features (and other fields). We were already correctly doing that, but tests were lacking. lightning/bolts#1242 added a test vector for invoices without payment secrets, which we're now verifying.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🦧
@TheBlueMatt I think we can merge that PR now, can't we? |
When decoding BOLT 11 invoices, LDK has always read them into fields, parsing what it can. When parsing features, this loses the information on the number of field elements which were used to encode the features in the invoice itself.
When we then go to calculate a hash of the invoice for signature validation/key recovery, we go re-serialize the invoice. At this point, any excess field elements used to encode features will be lost and the invoice's hash will be different from what the original encoder intended.
Luckily, this doesn't appear to have ever happened in practice. This was, in fact, only found by @erickcestari, @brunoerg, and @morehouse when doing differential fuzzing.
Because this hasn't happened and it breaks a straightforward way to handle BOLT 11 parsing, there's no reason to retain it, so instead here we simply forbid non-minimally-encoded features in BOLT 11 invoices.
See lightningdevkit/rust-lightning#3693 for the specific example generated by fuzzing.