zpay32: Fix broken last tagged field

This fixes an issue where the last tagged field of an invoice could get
broken due to the malleability of bech32 checksums.

The addition of a specific character in the second to last position of
the checksum could cause the previous signature field to mutate and thus
point to a different public node.
This commit is contained in:
Matheus Degiovani 2019-11-25 18:52:31 -03:00
parent 85f9c03797
commit 409cf55655

@ -90,6 +90,10 @@ var (
// ErrInvalidFieldLength is returned when a tagged field was specified
// with a length larger than the left over bytes of the data field.
ErrInvalidFieldLength = errors.New("invalid field length")
// ErrBrokenTaggedField is returned when the last tagged field is
// incorrectly formatted and doesn't have enough bytes to be read.
ErrBrokenTaggedField = errors.New("last tagged field is broken")
)
// MessageSigner is passed to the Encode method to provide a signature
@ -604,12 +608,14 @@ func parseTimestamp(data []byte) (uint64, error) {
// fills the Invoice struct accordingly.
func parseTaggedFields(invoice *Invoice, fields []byte, net *chaincfg.Params) error {
index := 0
for {
for len(fields)-index > 0 {
// If there are less than 3 groups to read, there cannot be more
// interesting information, as we need the type (1 group) and
// length (2 groups).
//
// This means the last tagged field is broken.
if len(fields)-index < 3 {
break
return ErrBrokenTaggedField
}
typ := fields[index]