manifest: add group signature length check

Refs. #1699.
This commit is contained in:
Roman Khimov 2021-02-08 15:11:31 +03:00
parent 296c7a10fc
commit e9ea89b4e3
6 changed files with 33 additions and 5 deletions

View file

@ -910,7 +910,7 @@ func TestRuntimeCheckWitness(t *testing.T) {
Hash: contractScriptHash, Hash: contractScriptHash,
NEF: *ne, NEF: *ne,
Manifest: manifest.Manifest{ Manifest: manifest.Manifest{
Groups: []manifest.Group{{PublicKey: pk.PublicKey()}}, Groups: []manifest.Group{{PublicKey: pk.PublicKey(), Signature: make([]byte, keys.SignatureLen)}},
}, },
} }
require.NoError(t, bc.contracts.Management.PutContractState(ic.DAO, contractState)) require.NoError(t, bc.contracts.Management.PutContractState(ic.DAO, contractState))

View file

@ -24,6 +24,9 @@ import (
// coordLen is the number of bytes in serialized X or Y coordinate. // coordLen is the number of bytes in serialized X or Y coordinate.
const coordLen = 32 const coordLen = 32
// SignatureLen is the length of standard signature for 256-bit EC key.
const SignatureLen = 64
// PublicKeys is a list of public keys. // PublicKeys is a list of public keys.
type PublicKeys []*PublicKey type PublicKeys []*PublicKey
@ -333,7 +336,7 @@ func (p *PublicKey) Address() string {
// Verify returns true if the signature is valid and corresponds // Verify returns true if the signature is valid and corresponds
// to the hash and public key. // to the hash and public key.
func (p *PublicKey) Verify(signature []byte, hash []byte) bool { func (p *PublicKey) Verify(signature []byte, hash []byte) bool {
if p.X == nil || p.Y == nil || len(signature) != 64 { if p.X == nil || p.Y == nil || len(signature) != SignatureLen {
return false return false
} }
rBytes := new(big.Int).SetBytes(signature[0:32]) rBytes := new(big.Int).SetBytes(signature[0:32])

View file

@ -57,6 +57,9 @@ func (g *Group) UnmarshalJSON(data []byte) error {
return err return err
} }
g.PublicKey = pub g.PublicKey = pub
if len(aux.Signature) != keys.SignatureLen {
return errors.New("wrong signature length")
}
g.Signature = aux.Signature g.Signature = aux.Signature
return nil return nil
} }
@ -90,6 +93,9 @@ func (g *Group) FromStackItem(item stackitem.Item) error {
if err != nil { if err != nil {
return err return err
} }
if len(sig) != keys.SignatureLen {
return errors.New("wrong signature length")
}
g.Signature = sig g.Signature = sig
return nil return nil
} }

View file

@ -0,0 +1,18 @@
package manifest
import (
"testing"
"github.com/nspcc-dev/neo-go/internal/testserdes"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/stretchr/testify/require"
)
func TestGroupJSONInOut(t *testing.T) {
priv, err := keys.NewPrivateKey()
require.NoError(t, err)
pub := priv.PublicKey()
sig := make([]byte, keys.SignatureLen)
g := Group{pub, sig}
testserdes.MarshalUnmarshalJSON(t, &g, new(Group))
}

View file

@ -199,7 +199,7 @@ func TestManifestToStackItem(t *testing.T) {
}, },
Groups: []Group{{ Groups: []Group{{
PublicKey: pk.PublicKey(), PublicKey: pk.PublicKey(),
Signature: []byte{1, 2, 3}, Signature: make([]byte, keys.SignatureLen),
}}, }},
Permissions: []Permission{*NewPermission(PermissionWildcard)}, Permissions: []Permission{*NewPermission(PermissionWildcard)},
SupportedStandards: []string{"NEP-17"}, SupportedStandards: []string{"NEP-17"},

View file

@ -117,11 +117,11 @@ func TestGroup_ToStackItemFromStackItem(t *testing.T) {
pk, _ := keys.NewPrivateKey() pk, _ := keys.NewPrivateKey()
g := &Group{ g := &Group{
PublicKey: pk.PublicKey(), PublicKey: pk.PublicKey(),
Signature: []byte{1, 2, 3}, Signature: make([]byte, keys.SignatureLen),
} }
expected := stackitem.NewStruct([]stackitem.Item{ expected := stackitem.NewStruct([]stackitem.Item{
stackitem.NewByteArray(pk.PublicKey().Bytes()), stackitem.NewByteArray(pk.PublicKey().Bytes()),
stackitem.NewByteArray([]byte{1, 2, 3}), stackitem.NewByteArray(make([]byte, keys.SignatureLen)),
}) })
CheckToFromStackItem(t, g, expected) CheckToFromStackItem(t, g, expected)
} }
@ -134,6 +134,7 @@ func TestGroup_FromStackItemErrors(t *testing.T) {
"invalid pub type": stackitem.NewStruct([]stackitem.Item{stackitem.NewInterop(nil), stackitem.Null{}}), "invalid pub type": stackitem.NewStruct([]stackitem.Item{stackitem.NewInterop(nil), stackitem.Null{}}),
"invalid pub bytes": stackitem.NewStruct([]stackitem.Item{stackitem.NewByteArray([]byte{1}), stackitem.Null{}}), "invalid pub bytes": stackitem.NewStruct([]stackitem.Item{stackitem.NewByteArray([]byte{1}), stackitem.Null{}}),
"invalid sig type": stackitem.NewStruct([]stackitem.Item{stackitem.NewByteArray(pk.Bytes()), stackitem.NewInterop(nil)}), "invalid sig type": stackitem.NewStruct([]stackitem.Item{stackitem.NewByteArray(pk.Bytes()), stackitem.NewInterop(nil)}),
"invalid sig len": stackitem.NewStruct([]stackitem.Item{stackitem.NewByteArray(pk.Bytes()), stackitem.NewByteArray([]byte{1})}),
} }
for name, errCase := range errCases { for name, errCase := range errCases {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {