frostfs-api-go/object/verification_test.go
alexvanin 81cdfcc502 object: Update verify routine
Verify routine now supports public key field to check
if integrity header contains correct signature of
object header.

Verify also have strict check that integrity header is
last header in the list of headers.
2020-01-16 17:32:57 +03:00

147 lines
3.5 KiB
Go

package object
import (
"testing"
"github.com/google/uuid"
crypto "github.com/nspcc-dev/neofs-crypto"
"github.com/nspcc-dev/neofs-crypto/test"
"github.com/nspcc-dev/neofs-proto/container"
"github.com/nspcc-dev/neofs-proto/refs"
"github.com/nspcc-dev/neofs-proto/session"
"github.com/stretchr/testify/require"
)
func TestObject_Verify(t *testing.T) {
key := test.DecodeKey(0)
sessionkey := test.DecodeKey(1)
payload := make([]byte, 1024*1024)
cnr, err := container.NewTestContainer()
require.NoError(t, err)
cid, err := cnr.ID()
require.NoError(t, err)
id, err := uuid.NewRandom()
uid := refs.UUID(id)
require.NoError(t, err)
obj := &Object{
SystemHeader: SystemHeader{
ID: uid,
CID: cid,
OwnerID: refs.OwnerID([refs.OwnerIDSize]byte{}),
},
Headers: []Header{
{
Value: &Header_UserHeader{
UserHeader: &UserHeader{
Key: "Profession",
Value: "Developer",
},
},
},
{
Value: &Header_UserHeader{
UserHeader: &UserHeader{
Key: "Language",
Value: "GO",
},
},
},
},
}
obj.SetPayload(payload)
obj.SetHeader(&Header{Value: &Header_PayloadChecksum{[]byte("incorrect checksum")}})
t.Run("error no integrity header and pubkey", func(t *testing.T) {
err = obj.Verify()
require.EqualError(t, err, ErrHeaderNotFound.Error())
})
badHeaderChecksum := []byte("incorrect checksum")
signature, err := crypto.Sign(sessionkey, badHeaderChecksum)
require.NoError(t, err)
ih := &IntegrityHeader{
HeadersChecksum: badHeaderChecksum,
ChecksumSignature: signature,
}
obj.SetHeader(&Header{Value: &Header_Integrity{ih}})
t.Run("error no validation header", func(t *testing.T) {
err = obj.Verify()
require.EqualError(t, err, ErrHeaderNotFound.Error())
})
dataPK := crypto.MarshalPublicKey(&sessionkey.PublicKey)
signature, err = crypto.Sign(key, dataPK)
vh := &session.VerificationHeader{
PublicKey: dataPK,
KeySignature: signature,
}
obj.SetVerificationHeader(vh)
// validation header is not last
t.Run("error validation header is not last", func(t *testing.T) {
err = obj.Verify()
require.EqualError(t, err, ErrHeaderNotFound.Error())
})
obj.Headers = obj.Headers[:len(obj.Headers)-2]
obj.SetVerificationHeader(vh)
obj.SetHeader(&Header{Value: &Header_Integrity{ih}})
t.Run("error invalid header checksum", func(t *testing.T) {
err = obj.Verify()
require.EqualError(t, err, ErrVerifyHeader.Error())
})
obj.Headers = obj.Headers[:len(obj.Headers)-1]
genIH, err := CreateIntegrityHeader(obj, sessionkey)
require.NoError(t, err)
obj.SetHeader(genIH)
t.Run("error invalid payload checksum", func(t *testing.T) {
err = obj.Verify()
require.EqualError(t, err, ErrVerifyPayload.Error())
})
obj.SetHeader(&Header{Value: &Header_PayloadChecksum{obj.PayloadChecksum()}})
obj.Headers = obj.Headers[:len(obj.Headers)-1]
genIH, err = CreateIntegrityHeader(obj, sessionkey)
require.NoError(t, err)
obj.SetHeader(genIH)
t.Run("correct with vh", func(t *testing.T) {
err = obj.Verify()
require.NoError(t, err)
})
pkh := Header{Value: &Header_PublicKey{&PublicKey{
Value: crypto.MarshalPublicKey(&key.PublicKey),
}}}
// replace vh with pkh
obj.Headers[len(obj.Headers)-2] = pkh
// re-sign object
obj.Sign(sessionkey)
t.Run("incorrect with bad public key", func(t *testing.T) {
err = obj.Verify()
require.Error(t, err)
})
obj.SetHeader(&Header{Value: &Header_PublicKey{&PublicKey{
Value: dataPK,
}}})
obj.Sign(sessionkey)
t.Run("correct with good public key", func(t *testing.T) {
err = obj.Verify()
require.NoError(t, err)
})
}