From 3f07313604febe08a063067e262b654d4f68cb7f Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Mon, 31 May 2021 11:55:38 +0300 Subject: [PATCH] [#562] cmd/neofs-node: use NEP-6 wallet for keys Also use neo-go private key wrapper where possible, as it already has methods for (un)marshaling. Signed-off-by: Evgenii Stratonikov --- cmd/neofs-node/accounting.go | 2 +- cmd/neofs-node/config.go | 10 +++---- cmd/neofs-node/config/control/config.go | 21 ++++++++++++-- cmd/neofs-node/config/control/config_test.go | 12 ++++---- cmd/neofs-node/config/node/config.go | 16 +++++++++++ cmd/neofs-node/config/node/config_test.go | 7 +++++ cmd/neofs-node/config/node/wallet.json | 30 ++++++++++++++++++++ cmd/neofs-node/container.go | 7 ++--- cmd/neofs-node/control.go | 24 +++++----------- cmd/neofs-node/morph.go | 2 +- cmd/neofs-node/netmap.go | 9 +++--- cmd/neofs-node/object.go | 7 +++-- cmd/neofs-node/reputation.go | 11 ++++--- cmd/neofs-node/session.go | 2 +- config/example/node.env | 3 ++ config/example/node.json | 5 ++++ config/example/node.yaml | 4 +++ 17 files changed, 119 insertions(+), 53 deletions(-) create mode 100644 cmd/neofs-node/config/node/wallet.json diff --git a/cmd/neofs-node/accounting.go b/cmd/neofs-node/accounting.go index e58426fc..e0491709 100644 --- a/cmd/neofs-node/accounting.go +++ b/cmd/neofs-node/accounting.go @@ -19,7 +19,7 @@ func initAccountingService(c *cfg) { accountingGRPC.RegisterAccountingServiceServer(c.cfgGRPC.server, accountingTransportGRPC.New( accountingService.NewSignService( - c.key, + &c.key.PrivateKey, accountingService.NewResponseService( accountingService.NewExecutionService( accounting.NewExecutor(balanceMorphWrapper), diff --git a/cmd/neofs-node/config.go b/cmd/neofs-node/config.go index c584bd6e..b721ddbc 100644 --- a/cmd/neofs-node/config.go +++ b/cmd/neofs-node/config.go @@ -2,18 +2,17 @@ package main import ( "context" - "crypto/ecdsa" "net" "os" "path" "sync" "time" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neofs-api-go/pkg" "github.com/nspcc-dev/neofs-api-go/pkg/netmap" netmapV2 "github.com/nspcc-dev/neofs-api-go/v2/netmap" - crypto "github.com/nspcc-dev/neofs-crypto" "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config" contractsconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/contracts" engineconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/engine" @@ -73,7 +72,7 @@ type cfg struct { wg *sync.WaitGroup - key *ecdsa.PrivateKey + key *keys.PrivateKey apiVersion *pkg.Version @@ -209,12 +208,11 @@ func initCfg(path string) *cfg { config.WithConfigFile(path), ) - key, err := crypto.LoadPrivateKey(nodeconfig.Key(appCfg)) - fatalOnErr(err) + key := nodeconfig.Wallet(appCfg) var logPrm logger.Prm - err = logPrm.SetLevelString( + err := logPrm.SetLevelString( loggerconfig.Level(appCfg), ) fatalOnErr(err) diff --git a/cmd/neofs-node/config/control/config.go b/cmd/neofs-node/config/control/config.go index e1b87668..ec43f991 100644 --- a/cmd/neofs-node/config/control/config.go +++ b/cmd/neofs-node/config/control/config.go @@ -1,6 +1,9 @@ package controlconfig import ( + "fmt" + + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config" ) @@ -18,12 +21,24 @@ const ( GRPCEndpointDefault = "" ) -// AuthorizedKeysString returns string array of "authorized_keys" config +// AuthorizedKeys parses and returns array of "authorized_keys" config // parameter from "control" section. // // Returns empty list if not set. -func AuthorizedKeysString(c *config.Config) []string { - return config.StringSliceSafe(c.Sub(subsection), "authorized_keys") +func AuthorizedKeys(c *config.Config) keys.PublicKeys { + strKeys := config.StringSliceSafe(c.Sub(subsection), "authorized_keys") + pubs := make(keys.PublicKeys, 0, len(strKeys)) + + for i := range strKeys { + pub, err := keys.NewPublicKeyFromString(strKeys[i]) + if err != nil { + panic(fmt.Errorf("invalid permitted key for Control service %s: %w", strKeys[i], err)) + } + + pubs = append(pubs, pub) + } + + return pubs } // GRPC returns structure that provides access to "grpc" subsection of diff --git a/cmd/neofs-node/config/control/config_test.go b/cmd/neofs-node/config/control/config_test.go index 7659580b..654c0f8b 100644 --- a/cmd/neofs-node/config/control/config_test.go +++ b/cmd/neofs-node/config/control/config_test.go @@ -3,6 +3,7 @@ package controlconfig_test import ( "testing" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config" controlconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/control" configtest "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/test" @@ -13,19 +14,18 @@ func TestControlSection(t *testing.T) { t.Run("defaults", func(t *testing.T) { empty := configtest.EmptyConfig() - require.Empty(t, controlconfig.AuthorizedKeysString(empty)) + require.Empty(t, controlconfig.AuthorizedKeys(empty)) require.Equal(t, controlconfig.GRPCEndpointDefault, controlconfig.GRPC(empty).Endpoint()) }) const path = "../../../../config/example/node" - var keys = []string{ - "035839e45d472a3b7769a2a1bd7d54c4ccd4943c3b40f547870e83a8fcbfb3ce11", - "028f42cfcb74499d7b15b35d9bff260a1c8d27de4f446a627406a382d8961486d6", - } + pubs := make(keys.PublicKeys, 2) + pubs[0], _ = keys.NewPublicKeyFromString("035839e45d472a3b7769a2a1bd7d54c4ccd4943c3b40f547870e83a8fcbfb3ce11") + pubs[1], _ = keys.NewPublicKeyFromString("028f42cfcb74499d7b15b35d9bff260a1c8d27de4f446a627406a382d8961486d6") var fileConfigTest = func(c *config.Config) { - require.Equal(t, keys, controlconfig.AuthorizedKeysString(c)) + require.Equal(t, pubs, controlconfig.AuthorizedKeys(c)) require.Equal(t, "127.0.0.1:8090", controlconfig.GRPC(c).Endpoint()) } diff --git a/cmd/neofs-node/config/node/config.go b/cmd/neofs-node/config/node/config.go index b78223ed..3c725092 100644 --- a/cmd/neofs-node/config/node/config.go +++ b/cmd/neofs-node/config/node/config.go @@ -5,8 +5,10 @@ import ( "fmt" "strconv" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config" "github.com/nspcc-dev/neofs-node/pkg/network" + utilConfig "github.com/nspcc-dev/neofs-node/pkg/util/config" ) const ( @@ -36,6 +38,20 @@ func Key(c *config.Config) string { return v } +// Wallet returns value of node private key from "node" section. +func Wallet(c *config.Config) *keys.PrivateKey { + v := c.Sub(subsection).Sub("wallet") + acc, err := utilConfig.LoadAccount( + config.String(v, "path"), + config.String(v, "address"), + config.String(v, "password")) + if err != nil { + panic(fmt.Errorf("invalid wallet config: %w", err)) + } + + return acc.PrivateKey() +} + // BootstrapAddress returns value of "address" config parameter // from "node" section as network.Address. // diff --git a/cmd/neofs-node/config/node/config_test.go b/cmd/neofs-node/config/node/config_test.go index a869a97e..041c6ef4 100644 --- a/cmd/neofs-node/config/node/config_test.go +++ b/cmd/neofs-node/config/node/config_test.go @@ -3,6 +3,7 @@ package nodeconfig import ( "testing" + "github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config" configtest "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/test" "github.com/nspcc-dev/neofs-node/pkg/network" @@ -43,6 +44,7 @@ func TestNodeSection(t *testing.T) { addr := BootstrapAddress(c) attributes := Attributes(c) relay := Relay(c) + wKey := Wallet(c) expectedAddr, err := network.AddressFromString("s01.neofs.devenv:8080") require.NoError(t, err) @@ -54,6 +56,11 @@ func TestNodeSection(t *testing.T) { require.Len(t, attributes, 2) require.Equal(t, "Price:11", attributes[0]) require.Equal(t, "UN-LOCODE:RU MSK", attributes[1]) + + require.NotNil(t, wKey) + require.Equal(t, + config.StringSafe(c.Sub("node").Sub("wallet"), "address"), + address.Uint160ToString(wKey.GetScriptHash())) } configtest.ForEachFileType(path, fileConfigTest) diff --git a/cmd/neofs-node/config/node/wallet.json b/cmd/neofs-node/config/node/wallet.json new file mode 100644 index 00000000..006d9602 --- /dev/null +++ b/cmd/neofs-node/config/node/wallet.json @@ -0,0 +1,30 @@ +{ + "version": "3.0", + "accounts": [ + { + "address": "NcpJzXcSDrh5CCizf4K9Ro6w4t59J5LKzz", + "key": "6PYXFRFUfoMNjWd2UmaaEjwHSWpifcLLTbEfhkwXdiSZ2n2WLfr75JpxmJ", + "label": "testacc", + "contract": { + "script": "DCECaeaVhKFa+ENNUpRJLz6BRmRbkIaoN+xZt3VHzlzkHJZBVuezJw==", + "parameters": [ + { + "name": "parameter0", + "type": "Signature" + } + ], + "deployed": false + }, + "lock": false, + "isDefault": false + } + ], + "scrypt": { + "n": 16384, + "r": 8, + "p": 8 + }, + "extra": { + "Tokens": null + } +} diff --git a/cmd/neofs-node/container.go b/cmd/neofs-node/container.go index 65c3ac5f..adabdc76 100644 --- a/cmd/neofs-node/container.go +++ b/cmd/neofs-node/container.go @@ -14,7 +14,6 @@ import ( "github.com/nspcc-dev/neofs-api-go/pkg/netmap" containerV2 "github.com/nspcc-dev/neofs-api-go/v2/container" containerGRPC "github.com/nspcc-dev/neofs-api-go/v2/container/grpc" - crypto "github.com/nspcc-dev/neofs-crypto" containerCore "github.com/nspcc-dev/neofs-node/pkg/core/container" netmapCore "github.com/nspcc-dev/neofs-node/pkg/core/netmap" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/engine" @@ -53,7 +52,7 @@ func initContainerService(c *cfg) { engine: c.cfgObject.cfgLocalStorage.localStorage, } - pubKey := crypto.MarshalPublicKey(&c.key.PublicKey) + pubKey := c.key.PublicKey().Bytes() resultWriter := &morphLoadWriter{ log: c.log, @@ -79,7 +78,7 @@ func initContainerService(c *cfg) { loadroute.Prm{ LocalServerInfo: c, RemoteWriterProvider: &remoteLoadAnnounceProvider{ - key: c.key, + key: &c.key.PrivateKey, loadAddrSrc: c, clientCache: clientCache, deadEndProvider: loadcontroller.SimpleWriterProvider(loadAccumulator), @@ -118,7 +117,7 @@ func initContainerService(c *cfg) { containerGRPC.RegisterContainerServiceServer(c.cfgGRPC.server, containerTransportGRPC.New( containerService.NewSignService( - c.key, + &c.key.PrivateKey, containerService.NewResponseService( &usedSpaceService{ Server: containerService.NewExecutionService(containerMorph.NewExecutor(wrap)), diff --git a/cmd/neofs-node/control.go b/cmd/neofs-node/control.go index 9234be1f..3b35ef01 100644 --- a/cmd/neofs-node/control.go +++ b/cmd/neofs-node/control.go @@ -2,12 +2,9 @@ package main import ( "context" - "encoding/hex" - "fmt" "net" "github.com/nspcc-dev/neofs-api-go/pkg/object" - crypto "github.com/nspcc-dev/neofs-crypto" controlconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/control" grpcconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/grpc" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/engine" @@ -17,25 +14,18 @@ import ( ) func initControlService(c *cfg) { - strKeys := controlconfig.AuthorizedKeysString(c.appCfg) - keys := make([][]byte, 0, len(strKeys)+1) // +1 for node key + pubs := controlconfig.AuthorizedKeys(c.appCfg) + rawPubs := make([][]byte, 0, len(pubs)+1) // +1 for node key - keys = append(keys, crypto.MarshalPublicKey(&c.key.PublicKey)) + rawPubs = append(rawPubs, c.key.PublicKey().Bytes()) - for i := range strKeys { - key, err := hex.DecodeString(strKeys[i]) - fatalOnErr(err) - - if crypto.UnmarshalPublicKey(key) == nil { - fatalOnErr(fmt.Errorf("invalid permitted key for Control service %s", strKeys[i])) - } - - keys = append(keys, key) + for i := range pubs { + rawPubs = append(rawPubs, pubs[i].Bytes()) } ctlSvc := controlSvc.New( - controlSvc.WithKey(c.key), - controlSvc.WithAuthorizedKeys(keys), + controlSvc.WithKey(&c.key.PrivateKey), + controlSvc.WithAuthorizedKeys(rawPubs), controlSvc.WithHealthChecker(c), controlSvc.WithNetMapSource(c.cfgNetmap.wrapper), controlSvc.WithNodeState(c), diff --git a/cmd/neofs-node/morph.go b/cmd/neofs-node/morph.go index 07adc34b..59e5b15a 100644 --- a/cmd/neofs-node/morph.go +++ b/cmd/neofs-node/morph.go @@ -30,7 +30,7 @@ func initMorphComponents(c *cfg) { }) for i := range addresses { - cli, err := client.New(c.key, addresses[i], client.WithDialTimeout(dialTimeout)) + cli, err := client.New(&c.key.PrivateKey, addresses[i], client.WithDialTimeout(dialTimeout)) if err == nil { c.log.Info("neo RPC connection established", zap.String("endpoint", addresses[i])) diff --git a/cmd/neofs-node/netmap.go b/cmd/neofs-node/netmap.go index bf433307..6d06ecc6 100644 --- a/cmd/neofs-node/netmap.go +++ b/cmd/neofs-node/netmap.go @@ -6,7 +6,6 @@ import ( netmapSDK "github.com/nspcc-dev/neofs-api-go/pkg/netmap" netmapV2 "github.com/nspcc-dev/neofs-api-go/v2/netmap" netmapGRPC "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc" - crypto "github.com/nspcc-dev/neofs-crypto" "github.com/nspcc-dev/neofs-node/pkg/core/netmap" "github.com/nspcc-dev/neofs-node/pkg/morph/event" netmapEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/netmap" @@ -75,7 +74,7 @@ func nodeAddressFromNetmap(c *cfg) string { func initNetmapService(c *cfg) { c.cfgNodeInfo.localInfo.SetAddress(c.localAddr.String()) - c.cfgNodeInfo.localInfo.SetPublicKey(crypto.MarshalPublicKey(&c.key.PublicKey)) + c.cfgNodeInfo.localInfo.SetPublicKey(c.key.PublicKey().Bytes()) c.cfgNodeInfo.localInfo.SetAttributes(parseAttributes(c.appCfg)...) c.cfgNodeInfo.localInfo.SetState(netmapSDK.NodeStateOffline) @@ -86,7 +85,7 @@ func initNetmapService(c *cfg) { netmapGRPC.RegisterNetmapServiceServer(c.cfgGRPC.server, netmapTransportGRPC.New( netmapService.NewSignService( - c.key, + &c.key.PrivateKey, netmapService.NewResponseService( netmapService.NewExecutionService( c, @@ -196,7 +195,7 @@ func (c *cfg) netmapLocalNodeState(epoch uint64) (*netmapSDK.NodeInfo, error) { func (c *cfg) localNodeInfoFromNetmap(nm *netmapSDK.Netmap) *netmapSDK.NodeInfo { for _, n := range nm.Nodes { - if bytes.Equal(n.PublicKey(), crypto.MarshalPublicKey(&c.key.PublicKey)) { + if bytes.Equal(n.PublicKey(), c.key.PublicKey().Bytes()) { return n.NodeInfo } } @@ -237,7 +236,7 @@ func (c *cfg) SetNetmapStatus(st control.NetmapStatus) error { c.cfgNetmap.reBoostrapTurnedOff.Store(true) return c.cfgNetmap.wrapper.UpdatePeerState( - crypto.MarshalPublicKey(&c.key.PublicKey), + c.key.PublicKey().Bytes(), apiState, ) } diff --git a/cmd/neofs-node/object.go b/cmd/neofs-node/object.go index a85aa20e..65efb40d 100644 --- a/cmd/neofs-node/object.go +++ b/cmd/neofs-node/object.go @@ -2,6 +2,7 @@ package main import ( "context" + "crypto/ecdsa" "crypto/sha256" "fmt" @@ -147,10 +148,10 @@ func (n *innerRingFetcher) InnerRingKeys() ([][]byte, error) { func initObjectService(c *cfg) { ls := c.cfgObject.cfgLocalStorage.localStorage - keyStorage := util.NewKeyStorage(c.key, c.privateTokenStore) + keyStorage := util.NewKeyStorage(&c.key.PrivateKey, c.privateTokenStore) nodeOwner := owner.NewID() - neo3Wallet, err := owner.NEO3WalletFromPublicKey(&c.key.PublicKey) + neo3Wallet, err := owner.NEO3WalletFromPublicKey((*ecdsa.PublicKey)(c.key.PublicKey())) fatalOnErr(err) nodeOwner.SetNeo3Wallet(neo3Wallet) @@ -325,7 +326,7 @@ func initObjectService(c *cfg) { ) signSvc := objectService.NewSignService( - c.key, + &c.key.PrivateKey, respSvc, ) diff --git a/cmd/neofs-node/reputation.go b/cmd/neofs-node/reputation.go index 6084383a..7a4dc7c0 100644 --- a/cmd/neofs-node/reputation.go +++ b/cmd/neofs-node/reputation.go @@ -7,7 +7,6 @@ import ( v2reputation "github.com/nspcc-dev/neofs-api-go/v2/reputation" v2reputationgrpc "github.com/nspcc-dev/neofs-api-go/v2/reputation/grpc" "github.com/nspcc-dev/neofs-api-go/v2/session" - crypto "github.com/nspcc-dev/neofs-crypto" "github.com/nspcc-dev/neofs-node/cmd/neofs-node/reputation/common" "github.com/nspcc-dev/neofs-node/cmd/neofs-node/reputation/intermediate" intermediatereputation "github.com/nspcc-dev/neofs-node/cmd/neofs-node/reputation/intermediate" @@ -38,7 +37,7 @@ func initReputationService(c *cfg) { wrap, err := rtpwrapper.NewFromMorph(c.cfgMorph.client, c.cfgReputation.scriptHash, 0) fatalOnErr(err) - localKey := crypto.MarshalPublicKey(&c.key.PublicKey) + localKey := c.key.PublicKey().Bytes() // consider sharing this between application components nmSrc := newCachedNetmapStorage(c.cfgNetmap.state, c.cfgNetmap.wrapper) @@ -99,7 +98,7 @@ func initReputationService(c *cfg) { ClientCache: apiClientCache, WriterProvider: localreputation.NewRemoteProvider( localreputation.RemoteProviderPrm{ - Key: c.key, + Key: &c.key.PrivateKey, }, ), }, @@ -112,7 +111,7 @@ func initReputationService(c *cfg) { ClientCache: apiClientCache, WriterProvider: intermediatereputation.NewRemoteProvider( intermediatereputation.RemoteProviderPrm{ - Key: c.key, + Key: &c.key.PrivateKey, }, ), }, @@ -144,7 +143,7 @@ func initReputationService(c *cfg) { WorkerPool: c.cfgReputation.workerPool, FinalResultTarget: intermediate.NewFinalWriterProvider( intermediate.FinalWriterProviderPrm{ - PrivatKey: c.key, + PrivatKey: &c.key.PrivateKey, PubKey: localKey, Client: wrap, }, @@ -190,7 +189,7 @@ func initReputationService(c *cfg) { v2reputationgrpc.RegisterReputationServiceServer(c.cfgGRPC.server, grpcreputation.New( reputationrpc.NewSignService( - c.key, + &c.key.PrivateKey, reputationrpc.NewResponseService( &reputationServer{ cfg: c, diff --git a/cmd/neofs-node/session.go b/cmd/neofs-node/session.go index a7bb9947..654236af 100644 --- a/cmd/neofs-node/session.go +++ b/cmd/neofs-node/session.go @@ -13,7 +13,7 @@ func initSessionService(c *cfg) { sessionGRPC.RegisterSessionServiceServer(c.cfgGRPC.server, sessionTransportGRPC.New( sessionSvc.NewSignService( - c.key, + &c.key.PrivateKey, sessionSvc.NewResponseService( sessionSvc.NewExecutionService( c.privateTokenStore, diff --git a/config/example/node.env b/config/example/node.env index 4d56ad36..42432837 100644 --- a/config/example/node.env +++ b/config/example/node.env @@ -8,6 +8,9 @@ NEOFS_METRICS_SHUTDOWN_TIMEOUT=15s # Node section NEOFS_NODE_KEY=path/hex/WIF +NEOFS_NODE_WALLET_PATH=./wallet.json +NEOFS_NODE_WALLET_ADDRESS=NcpJzXcSDrh5CCizf4K9Ro6w4t59J5LKzz +NEOFS_NODE_WALLET_PASSWORD=password NEOFS_NODE_ADDRESS=s01.neofs.devenv:8080 NEOFS_NODE_ATTRIBUTE_0=Price:11 NEOFS_NODE_ATTRIBUTE_1=UN-LOCODE:RU MSK diff --git a/config/example/node.json b/config/example/node.json index 61254461..646ccea5 100644 --- a/config/example/node.json +++ b/config/example/node.json @@ -12,6 +12,11 @@ }, "node": { "key": "path/hex/WIF", + "wallet": { + "path": "./wallet.json", + "address": "NcpJzXcSDrh5CCizf4K9Ro6w4t59J5LKzz", + "password": "password" + }, "address": "s01.neofs.devenv:8080", "attribute_0": "Price:11", "attribute_1": "UN-LOCODE:RU MSK", diff --git a/config/example/node.yaml b/config/example/node.yaml index ba0028e0..59b01a9f 100644 --- a/config/example/node.yaml +++ b/config/example/node.yaml @@ -11,6 +11,10 @@ metrics: node: key: path/hex/WIF + wallet: + path: "./wallet.json" + address: "NcpJzXcSDrh5CCizf4K9Ro6w4t59J5LKzz" + password: "password" address: s01.neofs.devenv:8080 attribute_0: "Price:11" attribute_1: UN-LOCODE:RU MSK