diff --git a/session/errors.go b/session/errors.go index 3a9c129..d35bed4 100644 --- a/session/errors.go +++ b/session/errors.go @@ -13,3 +13,7 @@ const ErrNilGPRCClientConn = internal.Error("gRPC client connection is nil") // ErrPrivateTokenNotFound is returned when addressed private token was // not found in storage. const ErrPrivateTokenNotFound = internal.Error("private token not found") + +// ErrNilPrivateToken is returned by functions that expect a non-nil +// PrivateToken, but received nil. +const ErrNilPrivateToken = internal.Error("private token is nil") diff --git a/session/private.go b/session/private.go index 6c9c68d..bb9242f 100644 --- a/session/private.go +++ b/session/private.go @@ -4,6 +4,8 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" + + crypto "github.com/nspcc-dev/neofs-crypto" ) type pToken struct { @@ -28,7 +30,24 @@ func NewPrivateToken(validUntil uint64) (PrivateToken, error) { }, nil } -// PrivateKey returns a binary representation of the session public key. +// PublicSessionToken returns a binary representation of session public key. +// +// If passed PrivateToken is nil, ErrNilPrivateToken returns. +// If passed PrivateToken carries nil private key, crypto.ErrEmptyPrivateKey returns. +func PublicSessionToken(pToken PrivateToken) ([]byte, error) { + if pToken == nil { + return nil, ErrNilPrivateToken + } + + sk := pToken.PrivateKey() + if sk == nil { + return nil, crypto.ErrEmptyPrivateKey + } + + return crypto.MarshalPublicKey(&sk.PublicKey), nil +} + +// PrivateKey is a session private key getter. func (t *pToken) PrivateKey() *ecdsa.PrivateKey { return t.sessionKey } diff --git a/session/private_test.go b/session/private_test.go index 9dedc29..c6f8125 100644 --- a/session/private_test.go +++ b/session/private_test.go @@ -3,6 +3,7 @@ package session import ( "testing" + crypto "github.com/nspcc-dev/neofs-crypto" "github.com/stretchr/testify/require" ) @@ -49,3 +50,27 @@ func TestPrivateTokenKey_SetTokenID(t *testing.T) { require.Equal(t, tokenID, s.token) } + +func TestPublicSessionToken(t *testing.T) { + var err error + + // nil PrivateToken + _, err = PublicSessionToken(nil) + require.EqualError(t, err, ErrNilPrivateToken.Error()) + + // empty private key + var pToken PrivateToken = new(pToken) + _, err = PublicSessionToken(pToken) + require.EqualError(t, err, crypto.ErrEmptyPrivateKey.Error()) + + // correct PrivateToken + pToken, err = NewPrivateToken(0) + require.NoError(t, err) + + key := pToken.PrivateKey() + require.NotNil(t, key) + + res, err := PublicSessionToken(pToken) + require.NoError(t, err) + require.Equal(t, res, crypto.MarshalPublicKey(&key.PublicKey)) +}