From aeb98842180299ead140597244131ba0c6a5652d Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Mon, 16 May 2022 16:15:31 +0300 Subject: [PATCH] [#1389] crypto: Upgrade SDK package Signed-off-by: Leonard Lyubich --- cmd/neofs-cli/modules/container.go | 12 +- cmd/neofs-cli/modules/control.go | 103 +++++++----------- cmd/neofs-cli/modules/dump.go | 11 +- cmd/neofs-cli/modules/object.go | 10 +- cmd/neofs-cli/modules/restore.go | 11 +- cmd/neofs-node/object.go | 18 ++- go.mod | 2 +- go.sum | Bin 98218 -> 98218 bytes pkg/core/object/fmt.go | 15 ++- pkg/innerring/processors/container/common.go | 3 +- pkg/morph/client/container/eacl.go | 17 ++- pkg/morph/client/container/eacl_set.go | 22 ++-- pkg/morph/client/container/get.go | 18 ++- pkg/morph/client/container/put.go | 27 +++-- pkg/services/container/morph/executor.go | 47 ++++++-- pkg/services/container/morph/executor_test.go | 10 +- pkg/services/control/ir/server/sign.go | 65 +++++++++-- pkg/services/control/server/sign.go | 65 +++++++++-- pkg/services/object/acl/v2/request.go | 2 +- pkg/services/object/acl/v2/util.go | 10 +- pkg/services/object/get/v2/util.go | 26 +++-- 21 files changed, 322 insertions(+), 172 deletions(-) diff --git a/cmd/neofs-cli/modules/container.go b/cmd/neofs-cli/modules/container.go index a9b86b5dc..6b5ea3b57 100644 --- a/cmd/neofs-cli/modules/container.go +++ b/cmd/neofs-cli/modules/container.go @@ -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)) diff --git a/cmd/neofs-cli/modules/control.go b/cmd/neofs-cli/modules/control.go index 3ef24e694..15234a789 100644 --- a/cmd/neofs-cli/modules/control.go +++ b/cmd/neofs-cli/modules/control.go @@ -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.") } diff --git a/cmd/neofs-cli/modules/dump.go b/cmd/neofs-cli/modules/dump.go index 4c9ee704d..94bc170d3 100644 --- a/cmd/neofs-cli/modules/dump.go +++ b/cmd/neofs-cli/modules/dump.go @@ -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.") } diff --git a/cmd/neofs-cli/modules/object.go b/cmd/neofs-cli/modules/object.go index b05cb5a51..79c4b6b10 100644 --- a/cmd/neofs-cli/modules/object.go +++ b/cmd/neofs-cli/modules/object.go @@ -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() diff --git a/cmd/neofs-cli/modules/restore.go b/cmd/neofs-cli/modules/restore.go index f201c2921..247615fff 100644 --- a/cmd/neofs-cli/modules/restore.go +++ b/cmd/neofs-cli/modules/restore.go @@ -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.") } diff --git a/cmd/neofs-node/object.go b/cmd/neofs-node/object.go index f339d6578..fe28a0ab2 100644 --- a/cmd/neofs-node/object.go +++ b/cmd/neofs-node/object.go @@ -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 diff --git a/go.mod b/go.mod index a3daaeb04..b7044cf26 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 0000c370834487560b3d8066b9c0fc209f6cf8a7..11c3cf584964dacac29c0f8b680f19d5b878279f 100644 GIT binary patch delta 106 zcmZ4WpLNxL)(yL7J6Rf7nwlCK>ZTYOSXx>d8X6}Wr7C0?TBT*Cm^c?XnLBwE7l&qK t2PT>Nl{jiUM;LhPCx`3j8JRm8gjl)+xJ4RIZk%l;g3XxC-gDv~0{}AhAyEJT delta 111 zcmZ4WpLNxL)(yL7I~yCC8Uul@Ws;e3vVnQBsby-CLWZGLNkMvqPh^f`LAsB=XLd@2 xdsRR|S%imaKvjOQg-1cCzGGIUtEs-5Z-~j{iPL2#&z~(Lg3YYW-gDv~0{~{)C8YoW diff --git a/pkg/core/object/fmt.go b/pkg/core/object/fmt.go index 2cc9c72d7..adf101d67 100644 --- a/pkg/core/object/fmt.go +++ b/pkg/core/object/fmt.go @@ -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 diff --git a/pkg/innerring/processors/container/common.go b/pkg/innerring/processors/container/common.go index 4612a3aea..19e716271 100644 --- a/pkg/innerring/processors/container/common.go +++ b/pkg/innerring/processors/container/common.go @@ -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) } diff --git a/pkg/morph/client/container/eacl.go b/pkg/morph/client/container/eacl.go index 93ea53fca..7d732d22a 100644 --- a/pkg/morph/client/container/eacl.go +++ b/pkg/morph/client/container/eacl.go @@ -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 } diff --git a/pkg/morph/client/container/eacl_set.go b/pkg/morph/client/container/eacl_set.go index 7f88c64c3..c2352006b 100644 --- a/pkg/morph/client/container/eacl_set.go +++ b/pkg/morph/client/container/eacl_set.go @@ -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. diff --git a/pkg/morph/client/container/get.go b/pkg/morph/client/container/get.go index 1da1b8a49..06f920951 100644 --- a/pkg/morph/client/container/get.go +++ b/pkg/morph/client/container/get.go @@ -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 } diff --git a/pkg/morph/client/container/put.go b/pkg/morph/client/container/put.go index 372360458..d463f4826 100644 --- a/pkg/morph/client/container/put.go +++ b/pkg/morph/client/container/put.go @@ -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 } diff --git a/pkg/services/container/morph/executor.go b/pkg/services/container/morph/executor.go index 44cafc302..ab1c1ae4d 100644 --- a/pkg/services/container/morph/executor.go +++ b/pkg/services/container/morph/executor.go @@ -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 diff --git a/pkg/services/container/morph/executor_test.go b/pkg/services/container/morph/executor_test.go index 0abaacd6d..aa43af4b4 100644 --- a/pkg/services/container/morph/executor_test.go +++ b/pkg/services/container/morph/executor_test.go @@ -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 }, }, diff --git a/pkg/services/control/ir/server/sign.go b/pkg/services/control/ir/server/sign.go index 56e63650d..bb9625dea 100644 --- a/pkg/services/control/ir/server/sign.go +++ b/pkg/services/control/ir/server/sign.go @@ -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 } diff --git a/pkg/services/control/server/sign.go b/pkg/services/control/server/sign.go index bf43b24bb..5d6c5d4da 100644 --- a/pkg/services/control/server/sign.go +++ b/pkg/services/control/server/sign.go @@ -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 } diff --git a/pkg/services/object/acl/v2/request.go b/pkg/services/object/acl/v2/request.go index 3c85bb725..547765bb0 100644 --- a/pkg/services/object/acl/v2/request.go +++ b/pkg/services/object/acl/v2/request.go @@ -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 } diff --git a/pkg/services/object/acl/v2/util.go b/pkg/services/object/acl/v2/util.go index 8d9a62fd7..91eb1631d 100644 --- a/pkg/services/object/acl/v2/util.go +++ b/pkg/services/object/acl/v2/util.go @@ -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 { diff --git a/pkg/services/object/get/v2/util.go b/pkg/services/object/get/v2/util.go index ffb65d26b..ec403ed0e 100644 --- a/pkg/services/object/get/v2/util.go +++ b/pkg/services/object/get/v2/util.go @@ -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)