lnd/zpay32/zbase32check_test.go
Alex Akselrod 55e693aa09 zpay32: fix decoding when payment request is too short
This commit fixes a panic that can result when a zpay32 payment request
that is too short (and possibly invalid) is attempted to be decoded.

To fix this bug, we now simply ensure that that after we decode the
zbase32 encoding, the resulting set of bytes is _exactly_ the length we
expect. A new error has been introduced to handle this case, and a
simple test has been added which ensures proper handling of short
payment requests.

Fixes #127.
2017-02-16 19:30:28 +08:00

106 lines
3.0 KiB
Go

package zpay32
import (
"bytes"
"testing"
"github.com/davecgh/go-spew/spew"
"github.com/roasbeef/btcd/btcec"
"github.com/roasbeef/btcutil"
)
var (
testPrivKey = []byte{
0x81, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
0x63, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17,
0xd, 0xe7, 0x95, 0xe4, 0xb7, 0x25, 0xb8, 0x4d,
0x1e, 0xb, 0x4c, 0xfd, 0x9e, 0xc5, 0x8c, 0xe9,
}
_, testPubKey = btcec.PrivKeyFromBytes(btcec.S256(), testPrivKey)
testPayHash = [32]byte{
0xb7, 0x94, 0x38, 0x5f, 0x2d, 0x1e, 0xf7, 0xab,
0x4d, 0x92, 0x73, 0xd1, 0x90, 0x63, 0x81, 0xb4,
0x4f, 0x2f, 0x6f, 0x25, 0x88, 0xa3, 0xef, 0xb9,
0x6a, 0x49, 0x18, 0x83, 0x31, 0x98, 0x47, 0x53,
}
)
func TestEncodeDecode(t *testing.T) {
testPubKey.Curve = nil
tests := []struct {
version int
payReq PaymentRequest
encoding string
}{
{
payReq: PaymentRequest{
Destination: testPubKey,
PaymentHash: testPayHash,
Amount: btcutil.Amount(50000),
},
encoding: "yj8p9uh793syszrd4giu66gtsqprp47cc6cqbdo3" +
"qaxi7sr63y6bbphw8bx148zzipg3rh6t1btadpnxf7z1mnfd76" +
"hsw1eaoca3ot4uyyyyyyyyydbib998je6o",
version: 1,
},
}
for i, test := range tests {
// First ensure encoding the test payment request string in the
// specified encoding.
encodedReq := Encode(&test.payReq)
if encodedReq != test.encoding {
t.Fatalf("encoding mismatch for %v: expected %v got %v",
spew.Sdump(test.payReq), test.encoding, encodedReq)
}
// Next ensure the correctness of the transformation in the
// other direction.
decodedReq, err := Decode(test.encoding)
if err != nil {
t.Fatalf("unable to decode invoice #%v: %v", i, err)
}
if !test.payReq.Destination.IsEqual(decodedReq.Destination) {
t.Fatalf("test #%v:, destination mismatch for decoded request: "+
"expected %v got %v", i, test.payReq.Destination,
decodedReq.Destination)
}
if !bytes.Equal(test.payReq.PaymentHash[:], decodedReq.PaymentHash[:]) {
t.Fatalf("test #%v: payment hash mismatch for decoded request: "+
"expected %x got %x", i, test.payReq.PaymentHash,
decodedReq.PaymentHash)
}
if test.payReq.Amount != decodedReq.Amount {
t.Fatalf("test #%v: amount mismatch for decoded request: "+
"expected %x got %x", i, test.payReq.Amount,
decodedReq.Amount)
}
}
}
func TestChecksumMismatch(t *testing.T) {
// We start with a pre-encoded invoice, which has a valid checksum.
payReqString := []byte("ycyr8brdjic6oak3bemztc5nupo56y3itq4z5q4qxwb35orf7fmj5phw8bx148zzipg3rh6t1btadpnxf7z1mnfd76hsw1eaoca3ot4uyyyyyyyyydbibt79jo1o")
// To modify the resulting checksum, we shift a few of the bytes within the
// string itself.
payReqString[1] = 98
payReqString[5] = 102
if _, err := Decode(string(payReqString)); err != ErrCheckSumMismatch {
t.Fatalf("decode should fail with checksum mismatch, instead: %v", err)
}
}
func TestDecodeTooShort(t *testing.T) {
// We start with a pre-encoded too-short string.
payReqString := "ycyr8brdji"
if _, err := Decode(payReqString); err != ErrDataTooShort {
t.Fatalf("decode should fail with data too short, instead: %v", err)
}
}