[#1389] crypto: Upgrade SDK package

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2022-05-16 16:15:31 +03:00 committed by LeL
parent 5e50ddd7f5
commit aeb9884218
21 changed files with 322 additions and 172 deletions

View file

@ -11,6 +11,7 @@ import (
"time"
"github.com/google/uuid"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client"
"github.com/nspcc-dev/neofs-node/pkg/core/version"
"github.com/nspcc-dev/neofs-sdk-go/acl"
@ -368,12 +369,19 @@ var getExtendedACLCmd = &cobra.Command{
sig := eaclTable.Signature()
// TODO(@cthulhu-rider): #1387 avoid type conversion
var sigV2 refs.Signature
sig.WriteToV2(&sigV2)
if containerPathTo == "" {
cmd.Println("eACL: ")
prettyPrintEACL(cmd, eaclTable)
var sigV2 refs.Signature
sig.WriteToV2(&sigV2)
cmd.Println("Signature:")
printJSONMarshaler(cmd, sig, "signature")
printJSONMarshaler(cmd, &sigV2, "signature")
return
}
@ -391,7 +399,7 @@ var getExtendedACLCmd = &cobra.Command{
cmd.Println("dumping data to file:", containerPathTo)
cmd.Println("Signature:")
printJSONMarshaler(cmd, sig, "signature")
printJSONMarshaler(cmd, &sigV2, "signature")
err = os.WriteFile(containerPathTo, data, 0644)
exitOnErr(cmd, errf("could not write eACL to file: %w", err))

View file

@ -2,17 +2,19 @@ package cmd
import (
"crypto/ecdsa"
"errors"
"fmt"
"github.com/mr-tron/base58"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
"github.com/nspcc-dev/neofs-node/pkg/services/control"
ircontrol "github.com/nspcc-dev/neofs-node/pkg/services/control/ir"
ircontrolsrv "github.com/nspcc-dev/neofs-node/pkg/services/control/ir/server"
controlSvc "github.com/nspcc-dev/neofs-node/pkg/services/control/server"
"github.com/nspcc-dev/neofs-sdk-go/client"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
"github.com/nspcc-dev/neofs-sdk-go/util/signature"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
@ -206,6 +208,36 @@ func init() {
initControlRestoreShardCmd()
}
func verifyResponseControl(cmd *cobra.Command,
sigControl interface {
GetKey() []byte
GetSign() []byte
},
body interface {
StableMarshal([]byte) ([]byte, error)
},
) {
if sigControl == nil {
exitOnErr(cmd, errors.New("missing response signature"))
}
bodyData, err := body.StableMarshal(nil)
exitOnErr(cmd, errf("marshal response body: %w", err))
// TODO(@cthulhu-rider): #1387 use Signature message from NeoFS API to avoid conversion
var sigV2 refs.Signature
sigV2.SetScheme(refs.ECDSA_SHA512)
sigV2.SetKey(sigControl.GetKey())
sigV2.SetSign(sigControl.GetSign())
var sig neofscrypto.Signature
sig.ReadFromV2(sigV2)
if !sig.Verify(bodyData) {
exitOnErr(cmd, errors.New("invalid response signature"))
}
}
func healthCheck(cmd *cobra.Command, _ []string) {
key, err := getKeyNoGenerate()
exitOnErr(cmd, err)
@ -232,15 +264,7 @@ func healthCheck(cmd *cobra.Command, _ []string) {
})
exitOnErr(cmd, errf("rpc error: %w", err))
sign := resp.GetSignature()
err = signature.VerifyDataWithSource(
resp,
func() ([]byte, []byte) {
return sign.GetKey(), sign.GetSign()
},
)
exitOnErr(cmd, errf("invalid response signature: %w", err))
verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody())
cmd.Printf("Network status: %s\n", resp.GetBody().GetNetmapStatus())
cmd.Printf("Health status: %s\n", resp.GetBody().GetHealthStatus())
@ -261,15 +285,7 @@ func healthCheckIR(cmd *cobra.Command, key *ecdsa.PrivateKey, c *client.Client)
})
exitOnErr(cmd, errf("rpc error: %w", err))
sign := resp.GetSignature()
err = signature.VerifyDataWithSource(
resp,
func() ([]byte, []byte) {
return sign.GetKey(), sign.GetSign()
},
)
exitOnErr(cmd, errf("invalid response signature: %w", err))
verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody())
cmd.Printf("Health status: %s\n", resp.GetBody().GetHealthStatus())
}
@ -311,15 +327,7 @@ func setNetmapStatus(cmd *cobra.Command, _ []string) {
})
exitOnErr(cmd, errf("rpc error: %w", err))
sign := resp.GetSignature()
err = signature.VerifyDataWithSource(
resp,
func() ([]byte, []byte) {
return sign.GetKey(), sign.GetSign()
},
)
exitOnErr(cmd, errf("invalid response signature: %w", err))
verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody())
cmd.Println("Network status update request successfully sent.")
}
@ -372,15 +380,7 @@ var dropObjectsCmd = &cobra.Command{
})
exitOnErr(cmd, errf("rpc error: %w", err))
sign := resp.GetSignature()
err = signature.VerifyDataWithSource(
resp,
func() ([]byte, []byte) {
return sign.GetKey(), sign.GetSign()
},
)
exitOnErr(cmd, errf("invalid response signature: %w", err))
verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody())
cmd.Println("Objects were successfully marked to be removed.")
},
@ -410,15 +410,7 @@ var snapshotCmd = &cobra.Command{
})
exitOnErr(cmd, errf("rpc error: %w", err))
sign := resp.GetSignature()
err = signature.VerifyDataWithSource(
resp,
func() ([]byte, []byte) {
return sign.GetKey(), sign.GetSign()
},
)
exitOnErr(cmd, errf("invalid response signature: %w", err))
verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody())
prettyPrintNetmap(cmd, resp.GetBody().GetNetmap(), netmapSnapshotJSON)
},
@ -444,14 +436,7 @@ func listShards(cmd *cobra.Command, _ []string) {
})
exitOnErr(cmd, errf("rpc error: %w", err))
sign := resp.GetSignature()
err = signature.VerifyDataWithSource(
resp,
func() ([]byte, []byte) {
return sign.GetKey(), sign.GetSign()
},
)
exitOnErr(cmd, errf("invalid response signature: %w", err))
verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody())
prettyPrintShards(cmd, resp.GetBody().GetShards())
}
@ -539,15 +524,7 @@ func setShardMode(cmd *cobra.Command, _ []string) {
})
exitOnErr(cmd, errf("rpc error: %w", err))
sign := resp.GetSignature()
err = signature.VerifyDataWithSource(
resp,
func() ([]byte, []byte) {
return sign.GetKey(), sign.GetSign()
},
)
exitOnErr(cmd, errf("invalid response signature: %w", err))
verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody())
cmd.Println("Shard mode update request successfully sent.")
}

View file

@ -5,7 +5,6 @@ import (
"github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
"github.com/nspcc-dev/neofs-node/pkg/services/control"
controlSvc "github.com/nspcc-dev/neofs-node/pkg/services/control/server"
"github.com/nspcc-dev/neofs-sdk-go/util/signature"
"github.com/spf13/cobra"
)
@ -53,15 +52,7 @@ func dumpShard(cmd *cobra.Command, _ []string) {
})
exitOnErr(cmd, errf("rpc error: %w", err))
sign := resp.GetSignature()
err = signature.VerifyDataWithSource(
resp,
func() ([]byte, []byte) {
return sign.GetKey(), sign.GetSign()
},
)
exitOnErr(cmd, errf("invalid response signature: %w", err))
verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody())
cmd.Println("Shard has been dumped successfully.")
}

View file

@ -16,6 +16,7 @@ import (
"github.com/cheggaaa/pb"
objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client"
sessionCli "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/modules/session"
"github.com/nspcc-dev/neofs-sdk-go/bearer"
@ -1065,8 +1066,13 @@ func printSplitHeader(cmd *cobra.Command, obj *object.Object) error {
if signature := obj.Signature(); signature != nil {
cmd.Print("Split Header Signature:\n")
cmd.Printf(" public key: %s\n", hex.EncodeToString(signature.Key()))
cmd.Printf(" signature: %s\n", hex.EncodeToString(signature.Sign()))
// TODO(@cthulhu-rider): #1387 implement and use another approach to avoid conversion
var sigV2 refs.Signature
signature.WriteToV2(&sigV2)
cmd.Printf(" public key: %s\n", hex.EncodeToString(sigV2.GetKey()))
cmd.Printf(" signature: %s\n", hex.EncodeToString(sigV2.GetSign()))
}
parent := obj.Parent()

View file

@ -5,7 +5,6 @@ import (
"github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
"github.com/nspcc-dev/neofs-node/pkg/services/control"
controlSvc "github.com/nspcc-dev/neofs-node/pkg/services/control/server"
"github.com/nspcc-dev/neofs-sdk-go/util/signature"
"github.com/spf13/cobra"
)
@ -53,15 +52,7 @@ func restoreShard(cmd *cobra.Command, _ []string) {
})
exitOnErr(cmd, errf("rpc error: %w", err))
sign := resp.GetSignature()
err = signature.VerifyDataWithSource(
resp,
func() ([]byte, []byte) {
return sign.GetKey(), sign.GetSign()
},
)
exitOnErr(cmd, errf("invalid response signature: %w", err))
verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody())
cmd.Println("Shard has been restored successfully.")
}

View file

@ -3,6 +3,7 @@ package main
import (
"bytes"
"context"
"errors"
"fmt"
"github.com/nspcc-dev/neofs-api-go/v2/object"
@ -43,7 +44,6 @@ import (
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
"github.com/nspcc-dev/neofs-sdk-go/owner"
"github.com/nspcc-dev/neofs-sdk-go/util/signature"
"go.uber.org/zap"
)
@ -418,8 +418,20 @@ func (s *morphEACLFetcher) GetEACL(cid *cid.ID) (*eaclSDK.Table, error) {
return nil, err
}
if err := signature.VerifyData((*signedEACLTable)(table), table.Signature(), signature.SignWithRFC6979()); err != nil {
return nil, fmt.Errorf("incorrect signature: %w", err)
sig := table.Signature()
if sig == nil {
// TODO(@cthulhu-rider): #1387 use "const" error
return nil, errors.New("missing signature")
}
binTable, err := table.Marshal()
if err != nil {
return nil, fmt.Errorf("marshal eACL table: %w", err)
}
if !sig.Verify(binTable) {
// TODO(@cthulhu-rider): #1387 use "const" error
return nil, errors.New("invalid signature of the eACL table")
}
return table, nil

2
go.mod
View file

@ -19,7 +19,7 @@ require (
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af // indirect
github.com/nspcc-dev/neofs-api-go/v2 v2.12.1
github.com/nspcc-dev/neofs-contract v0.14.2
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.3.0.20220413153333-9b63c07c59eb
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.3.0.20220419095511-d20999113a2e
github.com/nspcc-dev/tzhash v1.5.2
github.com/panjf2000/ants/v2 v2.4.0
github.com/paulmach/orb v0.2.2

BIN
go.sum

Binary file not shown.

View file

@ -10,6 +10,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-node/pkg/core/netmap"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/object"
@ -132,11 +133,21 @@ func (v *FormatValidator) Validate(obj *object.Object, unprepared bool) error {
}
func (v *FormatValidator) validateSignatureKey(obj *object.Object) error {
// FIXME(@cthulhu-rider): temp solution, see neofs-sdk-go#233
sig := obj.Signature()
if sig == nil {
// TODO(@cthulhu-rider): #1387 use "const" error
return errors.New("missing signature")
}
var sigV2 refs.Signature
sig.WriteToV2(&sigV2)
key := sigV2.GetKey()
token := obj.SessionToken()
key := obj.Signature().Key()
if token == nil || !bytes.Equal(token.SessionKey(), key) {
return v.checkOwnerKey(obj.OwnerID(), obj.Signature().Key())
return v.checkOwnerKey(obj.OwnerID(), key)
}
// FIXME: #1159 perform token verification

View file

@ -109,7 +109,8 @@ func (cp *Processor) checkSessionToken(token *session.Token) error {
// check token owner's key ownership
key, err := keys.NewPublicKeyFromBytes(token.Signature().Key(), elliptic.P256())
// FIXME(@cthulhu-rider): #1387 see neofs-sdk-go#233
key, err := keys.NewPublicKeyFromBytes(token.ToV2().GetSignature().GetKey(), elliptic.P256())
if err != nil {
return fmt.Errorf("invalid key: %w", err)
}

View file

@ -4,12 +4,13 @@ import (
"crypto/sha256"
"fmt"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
"github.com/nspcc-dev/neofs-sdk-go/eacl"
"github.com/nspcc-dev/neofs-sdk-go/session"
"github.com/nspcc-dev/neofs-sdk-go/signature"
)
// GetEACL reads the extended ACL table from NeoFS system
@ -86,11 +87,17 @@ func (c *Client) GetEACL(cnr *cid.ID) (*eacl.Table, error) {
table.SetSessionToken(tok)
}
tableSignature := signature.New()
tableSignature.SetKey(pub)
tableSignature.SetSign(sig)
// FIXME(@cthulhu-rider): #1387 temp solution, later table structure won't have a signature
table.SetSignature(tableSignature)
var sigV2 refs.Signature
sigV2.SetKey(pub)
sigV2.SetSign(sig)
sigV2.SetScheme(refs.ECDSA_RFC6979_SHA256)
var tableSignature neofscrypto.Signature
tableSignature.ReadFromV2(sigV2)
table.SetSignature(&tableSignature)
return table, nil
}

View file

@ -3,6 +3,7 @@ package container
import (
"fmt"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
"github.com/nspcc-dev/neofs-sdk-go/eacl"
)
@ -28,15 +29,20 @@ func PutEACL(c *Client, table *eacl.Table) error {
return fmt.Errorf("could not marshal session token: %w", err)
}
sig := table.Signature()
var prm PutEACLPrm
prm.SetTable(data)
prm.SetToken(binToken)
return c.PutEACL(
PutEACLPrm{
table: data,
key: sig.Key(),
sig: sig.Sign(),
token: binToken,
})
if sig := table.Signature(); sig != nil {
// TODO(@cthulhu-rider): #1387 implement and use another approach to avoid conversion
var sigV2 refs.Signature
sig.WriteToV2(&sigV2)
prm.SetKey(sigV2.GetKey())
prm.SetSignature(sigV2.GetSign())
}
return c.PutEACL(prm)
}
// PutEACLPrm groups parameters of PutEACL operation.

View file

@ -5,14 +5,15 @@ import (
"fmt"
"strings"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
containerContract "github.com/nspcc-dev/neofs-contract/container"
core "github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
"github.com/nspcc-dev/neofs-sdk-go/container"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
"github.com/nspcc-dev/neofs-sdk-go/session"
"github.com/nspcc-dev/neofs-sdk-go/signature"
)
type containerSource Client
@ -105,10 +106,17 @@ func (c *Client) Get(cid []byte) (*container.Container, error) {
cnr.SetSessionToken(tok)
}
sig := signature.New()
sig.SetKey(pub)
sig.SetSign(sigBytes)
cnr.SetSignature(sig)
// FIXME(@cthulhu-rider): #1387 temp solution, later table structure won't have a signature
var sigV2 refs.Signature
sigV2.SetKey(pub)
sigV2.SetSign(sigBytes)
sigV2.SetScheme(refs.ECDSA_RFC6979_SHA256)
var sig neofscrypto.Signature
sig.ReadFromV2(sigV2)
cnr.SetSignature(&sig)
return cnr, nil
}

View file

@ -4,6 +4,7 @@ import (
"crypto/sha256"
"fmt"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
"github.com/nspcc-dev/neofs-sdk-go/container"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
@ -28,18 +29,24 @@ func Put(c *Client, cnr *container.Container) (*cid.ID, error) {
return nil, fmt.Errorf("could not marshal session token: %w", err)
}
sig := cnr.Signature()
name, zone := container.GetNativeNameWithZone(cnr)
err = c.Put(PutPrm{
cnr: data,
key: sig.Key(),
sig: sig.Sign(),
token: binToken,
name: name,
zone: zone,
})
var prm PutPrm
prm.SetContainer(data)
prm.SetToken(binToken)
prm.SetName(name)
prm.SetZone(zone)
if sig := cnr.Signature(); sig != nil {
// TODO(@cthulhu-rider): #1387 implement and use another approach to avoid conversion
var sigV2 refs.Signature
sig.WriteToV2(&sigV2)
prm.SetKey(sigV2.GetKey())
prm.SetSignature(sigV2.GetSign())
}
err = c.Put(prm)
if err != nil {
return nil, err
}

View file

@ -12,10 +12,10 @@ import (
"github.com/nspcc-dev/neofs-node/pkg/services/object/acl/eacl"
containerSDK "github.com/nspcc-dev/neofs-sdk-go/container"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
eaclSDK "github.com/nspcc-dev/neofs-sdk-go/eacl"
"github.com/nspcc-dev/neofs-sdk-go/owner"
"github.com/nspcc-dev/neofs-sdk-go/session"
"github.com/nspcc-dev/neofs-sdk-go/signature"
)
type morphExecutor struct {
@ -56,11 +56,18 @@ func NewExecutor(rdr Reader, wrt Writer) containerSvc.ServiceExecutor {
}
func (s *morphExecutor) Put(ctx containerSvc.ContextWithToken, body *container.PutRequestBody) (*container.PutResponseBody, error) {
sigV2 := body.GetSignature()
if sigV2 == nil {
// TODO(@cthulhu-rider): #1387 use "const" error
return nil, errors.New("missing signature")
}
cnr := containerSDK.NewContainerFromV2(body.GetContainer())
cnr.SetSignature(
signature.NewFromV2(body.GetSignature()),
)
var sig neofscrypto.Signature
sig.ReadFromV2(*sigV2)
cnr.SetSignature(&sig)
tok := session.NewTokenFromV2(ctx.SessionToken)
if ctx.SessionToken != nil && session.GetContainerContext(tok) == nil {
@ -135,9 +142,16 @@ func (s *morphExecutor) Get(ctx context.Context, body *container.GetRequestBody)
return nil, err
}
var sigV2 *refs.Signature
if sig := cnr.Signature(); sig != nil {
sigV2 = new(refs.Signature)
sig.WriteToV2(sigV2)
}
res := new(container.GetResponseBody)
res.SetContainer(cnr.ToV2())
res.SetSignature(cnr.Signature().ToV2())
res.SetSignature(sigV2)
res.SetSessionToken(cnr.SessionToken().ToV2())
return res, nil
@ -163,10 +177,18 @@ func (s *morphExecutor) List(ctx context.Context, body *container.ListRequestBod
}
func (s *morphExecutor) SetExtendedACL(ctx containerSvc.ContextWithToken, body *container.SetExtendedACLRequestBody) (*container.SetExtendedACLResponseBody, error) {
table := eaclSDK.NewTableFromV2(body.GetEACL())
sign := signature.NewFromV2(body.GetSignature())
sigV2 := body.GetSignature()
if sigV2 == nil {
// TODO(@cthulhu-rider): #1387 use "const" error
return nil, errors.New("missing signature")
}
table.SetSignature(sign)
table := eaclSDK.NewTableFromV2(body.GetEACL())
var sig neofscrypto.Signature
sig.ReadFromV2(*sigV2)
table.SetSignature(&sig)
tok := session.NewTokenFromV2(ctx.SessionToken)
if ctx.SessionToken != nil && session.GetContainerContext(tok) == nil {
@ -201,9 +223,16 @@ func (s *morphExecutor) GetExtendedACL(ctx context.Context, body *container.GetE
return nil, err
}
var sigV2 *refs.Signature
if sig := table.Signature(); sig != nil {
sigV2 = new(refs.Signature)
sig.WriteToV2(sigV2)
}
res := new(container.GetExtendedACLResponseBody)
res.SetEACL(table.ToV2())
res.SetSignature(table.Signature().ToV2())
res.SetSignature(sigV2)
res.SetSessionToken(table.SessionToken().ToV2())
return res, nil

View file

@ -60,7 +60,10 @@ func TestInvalidToken(t *testing.T) {
{
name: "put",
op: func(e containerSvc.ServiceExecutor, ctx containerSvc.ContextWithToken) (err error) {
_, err = e.Put(ctx, new(container.PutRequestBody))
var reqBody container.PutRequestBody
reqBody.SetSignature(new(refs.Signature))
_, err = e.Put(ctx, &reqBody)
return
},
},
@ -77,7 +80,10 @@ func TestInvalidToken(t *testing.T) {
{
name: "setEACL",
op: func(e containerSvc.ServiceExecutor, ctx containerSvc.ContextWithToken) (err error) {
_, err = e.SetExtendedACL(ctx, new(container.SetExtendedACLRequestBody))
var reqBody container.SetExtendedACLRequestBody
reqBody.SetSignature(new(refs.Signature))
_, err = e.SetExtendedACL(ctx, &reqBody)
return
},
},

View file

@ -4,14 +4,17 @@ import (
"bytes"
"crypto/ecdsa"
"errors"
"fmt"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
control "github.com/nspcc-dev/neofs-node/pkg/services/control/ir"
"github.com/nspcc-dev/neofs-sdk-go/util/signature"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
)
// SignedMessage is an interface of Control service message.
type SignedMessage interface {
signature.DataSource
ReadSignedData([]byte) ([]byte, error)
GetSignature() *control.Signature
SetSignature(*control.Signature)
}
@ -19,8 +22,13 @@ type SignedMessage interface {
var errDisallowedKey = errors.New("key is not in the allowed list")
func (s *Server) isValidRequest(req SignedMessage) error {
sign := req.GetSignature()
if sign == nil {
// TODO(@cthulhu-rider): #1387 use "const" error
return errors.New("missing signature")
}
var (
sign = req.GetSignature()
key = sign.GetKey()
allowed = false
)
@ -37,18 +45,51 @@ func (s *Server) isValidRequest(req SignedMessage) error {
}
// verify signature
return signature.VerifyDataWithSource(req, func() ([]byte, []byte) {
return key, sign.GetSign()
})
binBody, err := req.ReadSignedData(nil)
if err != nil {
return fmt.Errorf("marshal request body: %w", err)
}
// TODO(@cthulhu-rider): #1387 use Signature message from NeoFS API to avoid conversion
var sigV2 refs.Signature
sigV2.SetKey(sign.GetKey())
sigV2.SetSign(sign.GetSign())
sigV2.SetScheme(refs.ECDSA_SHA512)
var sig neofscrypto.Signature
sig.ReadFromV2(sigV2)
if !sig.Verify(binBody) {
// TODO(@cthulhu-rider): #1387 use "const" error
return errors.New("invalid signature")
}
return nil
}
// SignMessage signs Control service message with private key.
func SignMessage(key *ecdsa.PrivateKey, msg SignedMessage) error {
return signature.SignDataWithHandler(key, msg, func(key []byte, sig []byte) {
s := new(control.Signature)
s.SetKey(key)
s.SetSign(sig)
binBody, err := msg.ReadSignedData(nil)
if err != nil {
return fmt.Errorf("marshal request body: %w", err)
}
msg.SetSignature(s)
})
var sig neofscrypto.Signature
err = sig.Calculate(neofsecdsa.Signer(*key), binBody)
if err != nil {
return fmt.Errorf("calculate signature: %w", err)
}
// TODO(@cthulhu-rider): #1387 use Signature message from NeoFS API to avoid conversion
var sigV2 refs.Signature
sig.WriteToV2(&sigV2)
var sigControl control.Signature
sigControl.SetKey(sigV2.GetKey())
sigControl.SetSign(sigV2.GetSign())
msg.SetSignature(&sigControl)
return nil
}

View file

@ -4,14 +4,17 @@ import (
"bytes"
"crypto/ecdsa"
"errors"
"fmt"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-node/pkg/services/control"
"github.com/nspcc-dev/neofs-sdk-go/util/signature"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
)
// SignedMessage is an interface of Control service message.
type SignedMessage interface {
signature.DataSource
ReadSignedData([]byte) ([]byte, error)
GetSignature() *control.Signature
SetSignature(*control.Signature)
}
@ -19,8 +22,13 @@ type SignedMessage interface {
var errDisallowedKey = errors.New("key is not in the allowed list")
func (s *Server) isValidRequest(req SignedMessage) error {
sign := req.GetSignature()
if sign == nil {
// TODO(@cthulhu-rider): #1387 use "const" error
return errors.New("missing signature")
}
var (
sign = req.GetSignature()
key = sign.GetKey()
allowed = false
)
@ -37,18 +45,51 @@ func (s *Server) isValidRequest(req SignedMessage) error {
}
// verify signature
return signature.VerifyDataWithSource(req, func() ([]byte, []byte) {
return key, sign.GetSign()
})
binBody, err := req.ReadSignedData(nil)
if err != nil {
return fmt.Errorf("marshal request body: %w", err)
}
// TODO(@cthulhu-rider): #1387 use Signature message from NeoFS API to avoid conversion
var sigV2 refs.Signature
sigV2.SetKey(sign.GetKey())
sigV2.SetSign(sign.GetSign())
sigV2.SetScheme(refs.ECDSA_SHA512)
var sig neofscrypto.Signature
sig.ReadFromV2(sigV2)
if !sig.Verify(binBody) {
// TODO(@cthulhu-rider): #1387 use "const" error
return errors.New("invalid signature")
}
return nil
}
// SignMessage signs Control service message with private key.
func SignMessage(key *ecdsa.PrivateKey, msg SignedMessage) error {
return signature.SignDataWithHandler(key, msg, func(key []byte, sig []byte) {
s := new(control.Signature)
s.SetKey(key)
s.SetSign(sig)
binBody, err := msg.ReadSignedData(nil)
if err != nil {
return fmt.Errorf("marshal request body: %w", err)
}
msg.SetSignature(s)
})
var sig neofscrypto.Signature
err = sig.Calculate(neofsecdsa.Signer(*key), binBody)
if err != nil {
return fmt.Errorf("calculate signature: %w", err)
}
// TODO(@cthulhu-rider): #1387 use Signature message from NeoFS API to avoid conversion
var sigV2 refs.Signature
sig.WriteToV2(&sigV2)
var sigControl control.Signature
sigControl.SetKey(sigV2.GetKey())
sigControl.SetSign(sigV2.GetSign())
msg.SetSignature(&sigControl)
return nil
}

View file

@ -129,7 +129,7 @@ func (r MetaWithToken) RequestOwner() (*owner.ID, *keys.PublicKey, error) {
return nil, nil, fmt.Errorf("%w: nil at body signature", ErrMalformedRequest)
}
key := unmarshalPublicKey(bodySignature.Key())
key := unmarshalPublicKey(bodySignature.GetKey())
return owner.NewIDFromPublicKey((*ecdsa.PublicKey)(key)), key, nil
}

View file

@ -16,7 +16,6 @@ import (
oidSDK "github.com/nspcc-dev/neofs-sdk-go/object/id"
"github.com/nspcc-dev/neofs-sdk-go/owner"
sessionSDK "github.com/nspcc-dev/neofs-sdk-go/session"
"github.com/nspcc-dev/neofs-sdk-go/signature"
)
var errMissingContainerID = errors.New("missing container ID")
@ -193,7 +192,10 @@ func ownerFromToken(token *sessionSDK.Token) (*owner.ID, *keys.PublicKey, error)
}
// 2. Then check if session token owner issued the session token
tokenIssuerKey := unmarshalPublicKey(token.Signature().Key())
// TODO(@cthulhu-rider): #1387 implement and use another approach to avoid conversion
tokV2 := token.ToV2()
tokenIssuerKey := unmarshalPublicKey(tokV2.GetSignature().GetKey())
tokenOwner := token.OwnerID()
if !isOwnerFromKey(tokenOwner, tokenIssuerKey) {
@ -204,7 +206,7 @@ func ownerFromToken(token *sessionSDK.Token) (*owner.ID, *keys.PublicKey, error)
return tokenOwner, tokenIssuerKey, nil
}
func originalBodySignature(v *sessionV2.RequestVerificationHeader) *signature.Signature {
func originalBodySignature(v *sessionV2.RequestVerificationHeader) *refsV2.Signature {
if v == nil {
return nil
}
@ -213,7 +215,7 @@ func originalBodySignature(v *sessionV2.RequestVerificationHeader) *signature.Si
v = v.GetOrigin()
}
return signature.NewFromV2(v.GetBodySignature())
return v.GetBodySignature()
}
func unmarshalPublicKey(bs []byte) *keys.PublicKey {

View file

@ -21,9 +21,9 @@ import (
getsvc "github.com/nspcc-dev/neofs-node/pkg/services/object/get"
"github.com/nspcc-dev/neofs-node/pkg/services/object/internal"
"github.com/nspcc-dev/neofs-node/pkg/services/object/util"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
"github.com/nspcc-dev/neofs-sdk-go/object"
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
signature2 "github.com/nspcc-dev/neofs-sdk-go/util/signature"
"github.com/nspcc-dev/tzhash/tz"
)
@ -434,18 +434,24 @@ func (s *Service) toHeadPrm(ctx context.Context, req *objectV2.HeadRequest, resp
return nil, errors.New("missing object ID")
}
if idSig == nil {
// TODO(@cthulhu-rider): #1387 use "const" error
return nil, errors.New("missing signature")
}
binID, err := id.Marshal()
if err != nil {
return nil, fmt.Errorf("marshal ID: %w", err)
}
var idV2 refs.ObjectID
id.WriteToV2(&idV2)
if err := signature2.VerifyDataWithSource(
signature.StableMarshalerWrapper{
SM: &idV2,
},
func() (key, sig []byte) {
return idSig.GetKey(), idSig.GetSign()
},
); err != nil {
return nil, fmt.Errorf("incorrect object header signature: %w", err)
var sig neofscrypto.Signature
sig.ReadFromV2(*idSig)
if !sig.Verify(binID) {
return nil, errors.New("invalid object ID signature")
}
case *objectV2.SplitInfo:
si := object.NewSplitInfoFromV2(v)