From af28735ca6f1eb95d6964a77fe0e07bb5fe63ce8 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Mon, 18 May 2020 13:11:39 +0300 Subject: [PATCH 1/2] session: change PrivateToken interface methods This commit replaces PublicKey() and SignData() methods of PrivateToken with PrivateKey() in order to have the ability to sign data with session key using service package functions. --- session/private.go | 13 +++---------- session/private_test.go | 23 ++--------------------- session/types.go | 10 ++-------- 3 files changed, 7 insertions(+), 39 deletions(-) diff --git a/session/private.go b/session/private.go index 42bb205..6c9c68d 100644 --- a/session/private.go +++ b/session/private.go @@ -4,8 +4,6 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" - - crypto "github.com/nspcc-dev/neofs-crypto" ) type pToken struct { @@ -30,14 +28,9 @@ func NewPrivateToken(validUntil uint64) (PrivateToken, error) { }, nil } -// Sign signs data with session private key. -func (t *pToken) Sign(data []byte) ([]byte, error) { - return crypto.Sign(t.sessionKey, data) -} - -// PublicKey returns a binary representation of the session public key. -func (t *pToken) PublicKey() []byte { - return crypto.MarshalPublicKey(&t.sessionKey.PublicKey) +// PrivateKey returns a binary representation of the session public key. +func (t *pToken) PrivateKey() *ecdsa.PrivateKey { + return t.sessionKey } func (t *pToken) Expired(epoch uint64) bool { diff --git a/session/private_test.go b/session/private_test.go index 8097b97..9dedc29 100644 --- a/session/private_test.go +++ b/session/private_test.go @@ -1,35 +1,16 @@ package session import ( - "crypto/rand" "testing" - crypto "github.com/nspcc-dev/neofs-crypto" "github.com/stretchr/testify/require" ) -func TestPrivateToken(t *testing.T) { +func TestPToken_PrivateKey(t *testing.T) { // create new private token pToken, err := NewPrivateToken(0) require.NoError(t, err) - - // generate data to sign - data := make([]byte, 10) - _, err = rand.Read(data) - require.NoError(t, err) - - // sign data via private token - sig, err := pToken.Sign(data) - require.NoError(t, err) - - // check signature - require.NoError(t, - crypto.Verify( - crypto.UnmarshalPublicKey(pToken.PublicKey()), - data, - sig, - ), - ) + require.NotNil(t, pToken.PrivateKey()) } func TestPToken_Expired(t *testing.T) { diff --git a/session/types.go b/session/types.go index ee13b92..95a0065 100644 --- a/session/types.go +++ b/session/types.go @@ -10,14 +10,8 @@ import ( // PrivateToken is an interface of session private part. type PrivateToken interface { - // PublicKey must return a binary representation of session public key. - PublicKey() []byte - - // Sign must return the signature of passed data. - // - // Resulting signature must be verified by crypto.Verify function - // with the session public key. - Sign([]byte) ([]byte, error) + // PrivateKey must return session private key. + PrivateKey() *ecdsa.PrivateKey // Expired must return true if and only if private token is expired in the given epoch number. Expired(uint64) bool From 291d5128400266fc5fc4192d2b6f30338ebfbe8a Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Mon, 18 May 2020 13:14:18 +0300 Subject: [PATCH 2/2] session: implement function for receiving session public key bytes After recent changes PrivateToken cannot directly return public key bytes. In order to provide this ability, this commit implements a function over PrivateToken interface. --- session/errors.go | 4 ++++ session/private.go | 21 ++++++++++++++++++++- session/private_test.go | 25 +++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) 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)) +}