package util import ( "crypto/ecdsa" "fmt" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/netmap" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/session/storage" apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user" "github.com/google/uuid" ) // SessionSource is an interface tha provides // access to node's actual (not expired) session // tokens. type SessionSource interface { // Get must return non-expired private token that // corresponds with passed owner and tokenID. If // token has not been created, has been expired // of it is impossible to get information about the // token Get must return nil. Get(owner user.ID, tokenID []byte) *storage.PrivateToken } // KeyStorage represents private key storage of the local node. type KeyStorage struct { key *ecdsa.PrivateKey tokenStore SessionSource networkState netmap.State } // NewKeyStorage creates, initializes and returns new KeyStorage instance. func NewKeyStorage(localKey *ecdsa.PrivateKey, tokenStore SessionSource, net netmap.State) *KeyStorage { return &KeyStorage{ key: localKey, tokenStore: tokenStore, networkState: net, } } // SessionInfo groups information about FrostFS Object session // which is reflected in KeyStorage. type SessionInfo struct { // Session unique identifier. ID uuid.UUID // Session issuer. Owner user.ID } // GetKey fetches private key depending on the SessionInfo. // // If info is not `nil`, searches for dynamic session token through the // underlying token storage. Returns apistatus.SessionTokenNotFound if // token storage does not contain information about provided dynamic session. // // If info is `nil`, returns node's private key. func (s *KeyStorage) GetKey(info *SessionInfo) (*ecdsa.PrivateKey, error) { if info != nil { binID, err := info.ID.MarshalBinary() if err != nil { return nil, fmt.Errorf("marshal ID: %w", err) } pToken := s.tokenStore.Get(info.Owner, binID) if pToken != nil { if pToken.ExpiredAt() <= s.networkState.CurrentEpoch() { return nil, new(apistatus.SessionTokenExpired) } return pToken.SessionKey(), nil } return nil, new(apistatus.SessionTokenNotFound) } return s.key, nil }