Skip to content

Commit 7964cdf

Browse files
committed
sphinx: max payload size check
1 parent 4b1b845 commit 7964cdf

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

sphinx.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"crypto/ecdsa"
66
"crypto/hmac"
77
"crypto/sha256"
8+
"fmt"
89
"io"
910
"math/big"
1011

@@ -73,6 +74,11 @@ const (
7374
baseVersion = 0
7475
)
7576

77+
var (
78+
ErrMaxRoutingInfoSizeExceeded = fmt.Errorf(
79+
"max routing info size of %v bytes exceeded", routingInfoSize)
80+
)
81+
7682
// OnionPacket is the onion wrapped hop-to-hop routing information necessary to
7783
// propagate a message through the mix-net without intermediate nodes having
7884
// knowledge of their position within the route, the source, the destination,
@@ -186,6 +192,11 @@ func generateSharedSecrets(paymentPath []*btcec.PublicKey,
186192
func NewOnionPacket(paymentPath *PaymentPath, sessionKey *btcec.PrivateKey,
187193
assocData []byte) (*OnionPacket, error) {
188194

195+
// Check whether total payload size doesn't exceed the hard maximum.
196+
if paymentPath.TotalPayloadSize() > routingInfoSize {
197+
return nil, ErrMaxRoutingInfoSizeExceeded
198+
}
199+
189200
numHops := paymentPath.TrueRouteLength()
190201

191202
hopSharedSecrets := generateSharedSecrets(

sphinx_test.go

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -563,8 +563,7 @@ func newEOBRoute(numHops uint32,
563563
)
564564
fwdMsg, err := NewOnionPacket(&route, sessionKey, nil)
565565
if err != nil {
566-
return nil, nil, fmt.Errorf("unable to create forwarding "+
567-
"message: %#v", err)
566+
return nil, nil, err
568567
}
569568

570569
return fwdMsg, nodes, nil
@@ -587,8 +586,9 @@ func TestSphinxHopVariableSizedPayloads(t *testing.T) {
587586
t.Parallel()
588587

589588
var testCases = []struct {
590-
numNodes uint32
591-
eobMapping map[int]HopPayload
589+
numNodes uint32
590+
eobMapping map[int]HopPayload
591+
expectedError error
592592
}{
593593
// A single hop route with a payload going to the last hop in
594594
// the route. The payload is enough to fit into what would be
@@ -678,16 +678,40 @@ func TestSphinxHopVariableSizedPayloads(t *testing.T) {
678678
},
679679
},
680680
},
681+
682+
// A 3 hop route (4 nodes) that carries more data then what fits
683+
// in the routing info.
684+
{
685+
numNodes: 3,
686+
eobMapping: map[int]HopPayload{
687+
0: HopPayload{
688+
Type: PayloadTLV,
689+
Payload: bytes.Repeat([]byte("a"), 500),
690+
},
691+
1: HopPayload{
692+
Type: PayloadTLV,
693+
Payload: bytes.Repeat([]byte("a"), 500),
694+
},
695+
2: HopPayload{
696+
Type: PayloadTLV,
697+
Payload: bytes.Repeat([]byte("a"), 500),
698+
},
699+
},
700+
expectedError: ErrMaxRoutingInfoSizeExceeded,
701+
},
681702
}
682703

683704
for testCaseNum, testCase := range testCases {
684705
nextPkt, routers, err := newEOBRoute(
685706
testCase.numNodes, testCase.eobMapping,
686707
)
687-
if err != nil {
708+
if testCase.expectedError != err {
688709
t.Fatalf("#%v: unable to create eob "+
689710
"route: %v", testCase, err)
690711
}
712+
if err != nil {
713+
continue
714+
}
691715

692716
// We'll now walk thru manually each actual hop within the
693717
// route. We use the size of the routers rather than the number

0 commit comments

Comments
 (0)