From e01fb0cc625ab164b3d15cc951c49b5aeab50a9a Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Mon, 11 May 2020 17:28:44 +0300 Subject: [PATCH] Implement signed data calculating function from SignedDataReader --- accounting/sign.go | 42 +++-------------- bootstrap/sign.go | 14 +++--- container/sign.go | 34 +++----------- object/sign.go | 103 ++++++++++++++++++------------------------ service/errors.go | 4 ++ service/token.go | 6 +-- service/utils.go | 18 ++++++++ service/utils_test.go | 34 ++++++++++++++ session/request.go | 10 +--- state/sign.go | 10 ++-- 10 files changed, 126 insertions(+), 149 deletions(-) create mode 100644 service/utils.go create mode 100644 service/utils_test.go diff --git a/accounting/sign.go b/accounting/sign.go index 4c6452d..1eabed4 100644 --- a/accounting/sign.go +++ b/accounting/sign.go @@ -3,17 +3,13 @@ package accounting import ( "encoding/binary" "io" + + "github.com/nspcc-dev/neofs-api-go/service" ) // SignedData returns payload bytes of the request. func (m BalanceRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - if _, err := m.ReadSignedData(data); err != nil { - return nil, err - } - - return data, nil + return service.SignedDataFromReader(m) } // SignedDataSize returns payload size of the request. @@ -37,13 +33,7 @@ func (m BalanceRequest) ReadSignedData(p []byte) (int, error) { // SignedData returns payload bytes of the request. func (m GetRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - if _, err := m.ReadSignedData(data); err != nil { - return nil, err - } - - return data, nil + return service.SignedDataFromReader(m) } // SignedDataSize returns payload size of the request. @@ -71,13 +61,7 @@ func (m GetRequest) ReadSignedData(p []byte) (int, error) { // SignedData returns payload bytes of the request. func (m PutRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - if _, err := m.ReadSignedData(data); err != nil { - return nil, err - } - - return data, nil + return service.SignedDataFromReader(m) } // SignedDataSize returns payload size of the request. @@ -125,13 +109,7 @@ func (m PutRequest) ReadSignedData(p []byte) (int, error) { // SignedData returns payload bytes of the request. func (m ListRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - if _, err := m.ReadSignedData(data); err != nil { - return nil, err - } - - return data, nil + return service.SignedDataFromReader(m) } // SignedDataSize returns payload size of the request. @@ -155,13 +133,7 @@ func (m ListRequest) ReadSignedData(p []byte) (int, error) { // SignedData returns payload bytes of the request. func (m DeleteRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - if _, err := m.ReadSignedData(data); err != nil { - return nil, err - } - - return data, nil + return service.SignedDataFromReader(m) } // SignedDataSize returns payload size of the request. diff --git a/bootstrap/sign.go b/bootstrap/sign.go index 97d8640..34f7fc2 100644 --- a/bootstrap/sign.go +++ b/bootstrap/sign.go @@ -1,16 +1,14 @@ package bootstrap -import "io" +import ( + "io" + + "github.com/nspcc-dev/neofs-api-go/service" +) // SignedData returns payload bytes of the request. func (m Request) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - if _, err := m.ReadSignedData(data); err != nil { - return nil, err - } - - return data, nil + return service.SignedDataFromReader(m) } // SignedDataSize returns payload size of the request. diff --git a/container/sign.go b/container/sign.go index 0f5fc93..eafd93c 100644 --- a/container/sign.go +++ b/container/sign.go @@ -3,19 +3,15 @@ package container import ( "encoding/binary" "io" + + service "github.com/nspcc-dev/neofs-api-go/service" ) var requestEndianness = binary.BigEndian // SignedData returns payload bytes of the request. func (m PutRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - if _, err := m.ReadSignedData(data); err != nil { - return nil, err - } - - return data, nil + return service.SignedDataFromReader(m) } // SignedDataSize returns payload size of the request. @@ -67,13 +63,7 @@ func (m PutRequest) ReadSignedData(p []byte) (int, error) { // SignedData returns payload bytes of the request. func (m DeleteRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - if _, err := m.ReadSignedData(data); err != nil { - return nil, err - } - - return data, nil + return service.SignedDataFromReader(m) } // SignedDataSize returns payload size of the request. @@ -98,13 +88,7 @@ func (m DeleteRequest) ReadSignedData(p []byte) (int, error) { // SignedData returns payload bytes of the request. func (m GetRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - if _, err := m.ReadSignedData(data); err != nil { - return nil, err - } - - return data, nil + return service.SignedDataFromReader(m) } // SignedDataSize returns payload size of the request. @@ -129,13 +113,7 @@ func (m GetRequest) ReadSignedData(p []byte) (int, error) { // SignedData returns payload bytes of the request. func (m ListRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - if _, err := m.ReadSignedData(data); err != nil { - return nil, err - } - - return data, nil + return service.SignedDataFromReader(m) } // SignedDataSize returns payload size of the request. diff --git a/object/sign.go b/object/sign.go index 25d0b2f..1ed3efa 100644 --- a/object/sign.go +++ b/object/sign.go @@ -3,34 +3,27 @@ package object import ( "encoding/binary" "io" + + "github.com/nspcc-dev/neofs-api-go/service" ) // SignedData returns payload bytes of the request. // // If payload is nil, ErrHeaderNotFound returns. func (m PutRequest) SignedData() ([]byte, error) { - sz := m.SignedDataSize() - if sz < 0 { - return nil, ErrHeaderNotFound - } - - data := make([]byte, sz) - - return data, m.ReadSignedData(data) + return service.SignedDataFromReader(m) } // ReadSignedData copies payload bytes to passed buffer. // // If the buffer size is insufficient, io.ErrUnexpectedEOF returns. -func (m PutRequest) ReadSignedData(p []byte) error { +func (m PutRequest) ReadSignedData(p []byte) (int, error) { r := m.GetR() if r == nil { - return ErrHeaderNotFound + return 0, ErrHeaderNotFound } - _, err := r.MarshalTo(p) - - return err + return r.MarshalTo(p) } // SignedDataSize returns the size of payload of the Put request. @@ -47,26 +40,26 @@ func (m PutRequest) SignedDataSize() int { // SignedData returns payload bytes of the request. func (m GetRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - return data, m.ReadSignedData(data) + return service.SignedDataFromReader(m) } // ReadSignedData copies payload bytes to passed buffer. // // If the buffer size is insufficient, io.ErrUnexpectedEOF returns. -func (m GetRequest) ReadSignedData(p []byte) error { +func (m GetRequest) ReadSignedData(p []byte) (int, error) { addr := m.GetAddress() if len(p) < m.SignedDataSize() { - return io.ErrUnexpectedEOF + return 0, io.ErrUnexpectedEOF } - off := copy(p, addr.CID.Bytes()) + var off int - copy(p[off:], addr.ObjectID.Bytes()) + off += copy(p[off:], addr.CID.Bytes()) - return nil + off += copy(p[off:], addr.ObjectID.Bytes()) + + return off, nil } // SignedDataSize returns payload size of the request. @@ -76,28 +69,28 @@ func (m GetRequest) SignedDataSize() int { // SignedData returns payload bytes of the request. func (m HeadRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - return data, m.ReadSignedData(data) + return service.SignedDataFromReader(m) } // ReadSignedData copies payload bytes to passed buffer. // // If the buffer size is insufficient, io.ErrUnexpectedEOF returns. -func (m HeadRequest) ReadSignedData(p []byte) error { +func (m HeadRequest) ReadSignedData(p []byte) (int, error) { if len(p) < m.SignedDataSize() { - return io.ErrUnexpectedEOF + return 0, io.ErrUnexpectedEOF } if m.GetFullHeaders() { p[0] = 1 } - off := 1 + copy(p[1:], m.Address.CID.Bytes()) + off := 1 - copy(p[off:], m.Address.ObjectID.Bytes()) + off += copy(p[off:], m.Address.CID.Bytes()) - return nil + off += copy(p[off:], m.Address.ObjectID.Bytes()) + + return off, nil } // SignedDataSize returns payload size of the request. @@ -107,24 +100,24 @@ func (m HeadRequest) SignedDataSize() int { // SignedData returns payload bytes of the request. func (m DeleteRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - return data, m.ReadSignedData(data) + return service.SignedDataFromReader(m) } // ReadSignedData copies payload bytes to passed buffer. // // If the buffer size is insufficient, io.ErrUnexpectedEOF returns. -func (m DeleteRequest) ReadSignedData(p []byte) error { +func (m DeleteRequest) ReadSignedData(p []byte) (int, error) { if len(p) < m.SignedDataSize() { - return io.ErrUnexpectedEOF + return 0, io.ErrUnexpectedEOF } - off := copy(p, m.OwnerID.Bytes()) + var off int - copy(p[off:], addressBytes(m.Address)) + off += copy(p[off:], m.OwnerID.Bytes()) - return nil + off += copy(p[off:], addressBytes(m.Address)) + + return off, nil } // SignedDataSize returns payload size of the request. @@ -134,27 +127,25 @@ func (m DeleteRequest) SignedDataSize() int { // SignedData returns payload bytes of the request. func (m GetRangeRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - return data, m.ReadSignedData(data) + return service.SignedDataFromReader(m) } // ReadSignedData copies payload bytes to passed buffer. // // If the buffer size is insufficient, io.ErrUnexpectedEOF returns. -func (m GetRangeRequest) ReadSignedData(p []byte) error { +func (m GetRangeRequest) ReadSignedData(p []byte) (int, error) { if len(p) < m.SignedDataSize() { - return io.ErrUnexpectedEOF + return 0, io.ErrUnexpectedEOF } n, err := (&m.Range).MarshalTo(p) if err != nil { - return err + return 0, err } - copy(p[n:], addressBytes(m.GetAddress())) + n += copy(p[n:], addressBytes(m.GetAddress())) - return nil + return n, nil } // SignedDataSize returns payload size of the request. @@ -164,17 +155,15 @@ func (m GetRangeRequest) SignedDataSize() int { // SignedData returns payload bytes of the request. func (m GetRangeHashRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - return data, m.ReadSignedData(data) + return service.SignedDataFromReader(m) } // ReadSignedData copies payload bytes to passed buffer. // // If the buffer size is insufficient, io.ErrUnexpectedEOF returns. -func (m GetRangeHashRequest) ReadSignedData(p []byte) error { +func (m GetRangeHashRequest) ReadSignedData(p []byte) (int, error) { if len(p) < m.SignedDataSize() { - return io.ErrUnexpectedEOF + return 0, io.ErrUnexpectedEOF } var off int @@ -185,7 +174,7 @@ func (m GetRangeHashRequest) ReadSignedData(p []byte) error { off += copy(p[off:], m.GetSalt()) - return nil + return off, nil } // SignedDataSize returns payload size of the request. @@ -203,17 +192,15 @@ func (m GetRangeHashRequest) SignedDataSize() int { // SignedData returns payload bytes of the request. func (m SearchRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - return data, m.ReadSignedData(data) + return service.SignedDataFromReader(m) } // ReadSignedData copies payload bytes to passed buffer. // // If the buffer size is insufficient, io.ErrUnexpectedEOF returns. -func (m SearchRequest) ReadSignedData(p []byte) error { +func (m SearchRequest) ReadSignedData(p []byte) (int, error) { if len(p) < m.SignedDataSize() { - return io.ErrUnexpectedEOF + return 0, io.ErrUnexpectedEOF } var off int @@ -223,9 +210,9 @@ func (m SearchRequest) ReadSignedData(p []byte) error { binary.BigEndian.PutUint32(p[off:], m.GetQueryVersion()) off += 4 - copy(p[off:], m.GetQuery()) + off += copy(p[off:], m.GetQuery()) - return nil + return off, nil } // SignedDataSize returns payload size of the request. diff --git a/service/errors.go b/service/errors.go index 6241ad2..f3a0dfc 100644 --- a/service/errors.go +++ b/service/errors.go @@ -43,3 +43,7 @@ const ErrNilDataWithTokenSignAccumulator = internal.Error("signed data with toke // ErrNilSignatureKeySourceWithToken is returned by functions that expect // a non-nil SignatureKeySourceWithToken, but received nil. const ErrNilSignatureKeySourceWithToken = internal.Error("key-signature source with token is nil") + +// ErrNilSignedDataReader is returned by functions that expect +// a non-nil SignedDataReader, but received nil. +const ErrNilSignedDataReader = internal.Error("signed data reader is nil") diff --git a/service/token.go b/service/token.go index 78fccfa..32c390f 100644 --- a/service/token.go +++ b/service/token.go @@ -123,11 +123,7 @@ func (m *Token) AddSignKey(sig []byte, _ *ecdsa.PublicKey) { // SignedData returns token information in a binary representation. func (m *Token) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - copyTokenSignedData(data, m) - - return data, nil + return SignedDataFromReader(m) } // ReadSignedData copies a binary representation of the token information to passed buffer. diff --git a/service/utils.go b/service/utils.go new file mode 100644 index 0000000..17b23bb --- /dev/null +++ b/service/utils.go @@ -0,0 +1,18 @@ +package service + +// SignedDataFromReader allocates buffer and reads bytes from passed reader to it. +// +// If passed SignedDataReader is nil, ErrNilSignedDataReader returns. +func SignedDataFromReader(r SignedDataReader) ([]byte, error) { + if r == nil { + return nil, ErrNilSignedDataReader + } + + data := make([]byte, r.SignedDataSize()) + + if _, err := r.ReadSignedData(data); err != nil { + return nil, err + } + + return data, nil +} diff --git a/service/utils_test.go b/service/utils_test.go new file mode 100644 index 0000000..60a2352 --- /dev/null +++ b/service/utils_test.go @@ -0,0 +1,34 @@ +package service + +import ( + "testing" + + "github.com/pkg/errors" + "github.com/stretchr/testify/require" +) + +func TestSignedDataFromReader(t *testing.T) { + // nil SignedDataReader + _, err := SignedDataFromReader(nil) + require.EqualError(t, err, ErrNilSignedDataReader.Error()) + + rdr := &testSignedDataReader{ + testSignedDataSrc: new(testSignedDataSrc), + } + + // make reader to return an error + rdr.err = errors.New("test error") + + _, err = SignedDataFromReader(rdr) + require.EqualError(t, err, rdr.err.Error()) + + // remove the error + rdr.err = nil + + // fill the data + rdr.data = testData(t, 10) + + res, err := SignedDataFromReader(rdr) + require.NoError(t, err) + require.Equal(t, rdr.data, res) +} diff --git a/session/request.go b/session/request.go index 0bb5176..73c05e5 100644 --- a/session/request.go +++ b/session/request.go @@ -5,6 +5,7 @@ import ( "io" "github.com/nspcc-dev/neofs-api-go/refs" + "github.com/nspcc-dev/neofs-api-go/service" ) const signedRequestDataSize = 0 + @@ -31,14 +32,7 @@ func (m *CreateRequest) SetOwnerID(id OwnerID) { // SignedData returns payload bytes of the request. func (m CreateRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - _, err := m.ReadSignedData(data) - if err != nil { - return nil, err - } - - return data, nil + return service.SignedDataFromReader(m) } // SignedDataSize returns payload size of the request. diff --git a/state/sign.go b/state/sign.go index 9193ebc..88f038c 100644 --- a/state/sign.go +++ b/state/sign.go @@ -2,6 +2,8 @@ package state import ( "io" + + "github.com/nspcc-dev/neofs-api-go/service" ) // SignedData returns payload bytes of the request. @@ -41,13 +43,7 @@ func (m DumpVarsRequest) SignedData() ([]byte, error) { // SignedData returns payload bytes of the request. func (m ChangeStateRequest) SignedData() ([]byte, error) { - data := make([]byte, m.SignedDataSize()) - - if _, err := m.ReadSignedData(data); err != nil { - return nil, err - } - - return data, nil + return service.SignedDataFromReader(m) } // SignedDataSize returns payload size of the request.