From 2fbdcbdee199338a6d9114d4e3200639cbc81a6a Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Mon, 25 Oct 2021 15:19:50 +0300 Subject: [PATCH] [#943] service/object: Check session token expiration Signed-off-by: Alex Vanin --- cmd/neofs-node/object.go | 2 +- pkg/services/object/util/key.go | 20 +++++++++++++++----- pkg/services/object/util/key_test.go | 16 +++++++++++++++- pkg/services/session/storage/types.go | 5 +++++ 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/cmd/neofs-node/object.go b/cmd/neofs-node/object.go index bc1303052..548873dce 100644 --- a/cmd/neofs-node/object.go +++ b/cmd/neofs-node/object.go @@ -177,7 +177,7 @@ func (x *coreClientConstructor) Get(info coreclient.NodeInfo) (coreclient.Client func initObjectService(c *cfg) { ls := c.cfgObject.cfgLocalStorage.localStorage - keyStorage := util.NewKeyStorage(&c.key.PrivateKey, c.privateTokenStore) + keyStorage := util.NewKeyStorage(&c.key.PrivateKey, c.privateTokenStore, c.cfgNetmap.state) nodeOwner := owner.NewID() neo3Wallet, err := owner.NEO3WalletFromPublicKey((*ecdsa.PublicKey)(c.key.PublicKey())) diff --git a/pkg/services/object/util/key.go b/pkg/services/object/util/key.go index ae389d08f..74c8c05df 100644 --- a/pkg/services/object/util/key.go +++ b/pkg/services/object/util/key.go @@ -5,24 +5,31 @@ import ( "errors" "github.com/nspcc-dev/neofs-api-go/pkg/session" + "github.com/nspcc-dev/neofs-node/pkg/core/netmap" "github.com/nspcc-dev/neofs-node/pkg/services/session/storage" ) -// todo(alexvanin): should be a part of status API -var errNoSessionToken = errors.New("session token does not exist") +var ( + // todo(alexvanin): should be a part of status API + errNoSessionToken = errors.New("session token does not exist") + errSessionTokenExpired = errors.New("session token has been expired") +) // KeyStorage represents private key storage of the local node. type KeyStorage struct { key *ecdsa.PrivateKey tokenStore *storage.TokenStore + + networkState netmap.State } // NewKeyStorage creates, initializes and returns new KeyStorage instance. -func NewKeyStorage(localKey *ecdsa.PrivateKey, tokenStore *storage.TokenStore) *KeyStorage { +func NewKeyStorage(localKey *ecdsa.PrivateKey, tokenStore *storage.TokenStore, net netmap.State) *KeyStorage { return &KeyStorage{ - key: localKey, - tokenStore: tokenStore, + key: localKey, + tokenStore: tokenStore, + networkState: net, } } @@ -34,6 +41,9 @@ func (s *KeyStorage) GetKey(token *session.Token) (*ecdsa.PrivateKey, error) { if token != nil { pToken := s.tokenStore.Get(token.OwnerID(), token.ID()) if pToken != nil { + if pToken.ExpiredAt() <= s.networkState.CurrentEpoch() { + return nil, errSessionTokenExpired + } return pToken.SessionKey(), nil } return nil, errNoSessionToken diff --git a/pkg/services/object/util/key_test.go b/pkg/services/object/util/key_test.go index 31585508a..19af7a19a 100644 --- a/pkg/services/object/util/key_test.go +++ b/pkg/services/object/util/key_test.go @@ -19,7 +19,7 @@ func TestNewKeyStorage(t *testing.T) { require.NoError(t, err) tokenStor := tokenStorage.New() - stor := util.NewKeyStorage(&nodeKey.PrivateKey, tokenStor) + stor := util.NewKeyStorage(&nodeKey.PrivateKey, tokenStor, mockedNetworkState{42}) t.Run("node key", func(t *testing.T) { key, err := stor.GetKey(nil) @@ -43,6 +43,12 @@ func TestNewKeyStorage(t *testing.T) { require.Equal(t, pubKey.X, key.PublicKey.X) require.Equal(t, pubKey.Y, key.PublicKey.Y) }) + + t.Run("expired token", func(t *testing.T) { + tok := createToken(t, tokenStor, 30) + _, err := stor.GetKey(tok) + require.Error(t, err) + }) } func generateToken(t *testing.T) *session.Token { @@ -74,3 +80,11 @@ func createToken(t *testing.T, store *tokenStorage.TokenStore, exp uint64) *sess return tok } + +type mockedNetworkState struct { + value uint64 +} + +func (m mockedNetworkState) CurrentEpoch() uint64 { + return m.value +} diff --git a/pkg/services/session/storage/types.go b/pkg/services/session/storage/types.go index 0332a0512..76d61afe3 100644 --- a/pkg/services/session/storage/types.go +++ b/pkg/services/session/storage/types.go @@ -15,3 +15,8 @@ type PrivateToken struct { func (t *PrivateToken) SessionKey() *ecdsa.PrivateKey { return t.sessionKey } + +// ExpiredAt returns epoch number until token is valid. +func (t *PrivateToken) ExpiredAt() uint64 { + return t.exp +}