Skip to content

Commit 492bd3c

Browse files
committed
Add new protobuf checks to Go
1 parent 062fa72 commit 492bd3c

File tree

3 files changed

+43
-2
lines changed

3 files changed

+43
-2
lines changed

go/ops.go

+11
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package ics23
33
import (
44
"bytes"
55
"crypto"
6+
67
// adds sha256 capability to crypto.SHA256
78
_ "crypto/sha256"
89
// adds sha512 capability to crypto.SHA512
@@ -69,10 +70,20 @@ func (op *InnerOp) Apply(child []byte) ([]byte, error) {
6970

7071
// CheckAgainstSpec will verify the InnerOp is in the format defined in spec
7172
func (op *InnerOp) CheckAgainstSpec(spec *ProofSpec) error {
73+
if op.Hash != spec.InnerSpec.Hash {
74+
return errors.Errorf("Unexpected HashOp: %d", op.Hash)
75+
}
76+
7277
leafPrefix := spec.LeafSpec.Prefix
7378
if bytes.HasPrefix(op.Prefix, leafPrefix) {
7479
return errors.Errorf("Inner Prefix starts with %X", leafPrefix)
7580
}
81+
if len(op.Prefix) < int(spec.InnerSpec.MinPrefixLength) {
82+
return errors.Errorf("InnerOp prefix too short (%d)", len(op.Prefix))
83+
}
84+
if len(op.Prefix) > int(spec.InnerSpec.MaxPrefixLength) {
85+
return errors.Errorf("InnerOp prefix too long (%d)", len(op.Prefix))
86+
}
7687
return nil
7788
}
7889

go/proof.go

+10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package ics23
22

33
import (
44
"bytes"
5+
56
"github.com/pkg/errors"
67
)
78

@@ -18,6 +19,7 @@ var IavlSpec = &ProofSpec{
1819
MinPrefixLength: 4,
1920
MaxPrefixLength: 12,
2021
ChildSize: 33, // (with length byte)
22+
Hash: HashOp_SHA256,
2123
},
2224
}
2325

@@ -34,6 +36,7 @@ var TendermintSpec = &ProofSpec{
3436
MinPrefixLength: 1,
3537
MaxPrefixLength: 1,
3638
ChildSize: 32, // (no length byte)
39+
Hash: HashOp_SHA256,
3740
},
3841
}
3942

@@ -96,6 +99,13 @@ func (p *ExistenceProof) CheckAgainstSpec(spec *ProofSpec) error {
9699
if err != nil {
97100
return errors.WithMessage(err, "leaf")
98101
}
102+
if spec.MinDepth > 0 && len(p.Path) < int(spec.MinDepth) {
103+
return errors.Errorf("InnerOps depth too short: %d", len(p.Path))
104+
}
105+
if spec.MaxDepth > 0 && len(p.Path) > int(spec.MaxDepth) {
106+
return errors.Errorf("InnerOps depth too long: %d", len(p.Path))
107+
}
108+
99109
for _, inner := range p.Path {
100110
if err := inner.CheckAgainstSpec(spec); err != nil {
101111
return errors.WithMessage(err, "inner")

go/proof_test.go

+22-2
Original file line numberDiff line numberDiff line change
@@ -237,12 +237,18 @@ func TestCheckLeaf(t *testing.T) {
237237

238238
func TestCheckAgainstSpec(t *testing.T) {
239239
validInner := &InnerOp{
240-
Prefix: fromHex("aa"),
240+
Hash: HashOp_SHA256,
241+
Prefix: fromHex("aabbccdd"),
241242
}
242243
invalidInner := &InnerOp{
243-
Prefix: fromHex("00aa"),
244+
Hash: HashOp_SHA256,
245+
Prefix: fromHex("00aabbccdd"),
244246
Suffix: fromHex("bb"),
245247
}
248+
invalidInner2 := &InnerOp{
249+
Hash: HashOp_SHA512,
250+
Prefix: fromHex("aabbccdd"),
251+
}
246252

247253
cases := map[string]struct {
248254
proof *ExistenceProof
@@ -315,6 +321,20 @@ func TestCheckAgainstSpec(t *testing.T) {
315321
spec: IavlSpec,
316322
isErr: true,
317323
},
324+
"rejects leaf with invalid inner proof (hash mismatch)": {
325+
proof: &ExistenceProof{
326+
Key: []byte("food"),
327+
Value: []byte("bar"),
328+
Leaf: IavlSpec.LeafSpec,
329+
Path: []*InnerOp{
330+
invalidInner2,
331+
validInner,
332+
validInner,
333+
},
334+
},
335+
spec: IavlSpec,
336+
isErr: true,
337+
},
318338
}
319339

320340
for name, tc := range cases {

0 commit comments

Comments
 (0)