Merge pull request #36 from nspcc-dev/public-keys-in-token

Public keys in token
This commit is contained in:
Alex Vanin 2020-01-17 13:57:59 +03:00 committed by GitHub
commit 038f934da5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 30 additions and 2 deletions

View file

@ -115,6 +115,7 @@ User token granting rights for object manipulation
| ObjectID | [bytes](#bytes) | repeated | ObjectID is an object identifier of manipulation object | | ObjectID | [bytes](#bytes) | repeated | ObjectID is an object identifier of manipulation object |
| Signature | [bytes](#bytes) | | Signature is a token signature, signed by owner of manipulation object | | Signature | [bytes](#bytes) | | Signature is a token signature, signed by owner of manipulation object |
| ID | [bytes](#bytes) | | ID is a token identifier. valid UUIDv4 represented in bytes | | ID | [bytes](#bytes) | | ID is a token identifier. valid UUIDv4 represented in bytes |
| PublicKeys | [bytes](#bytes) | repeated | PublicKeys associated with owner |
<a name="session.VerificationHeader"></a> <a name="session.VerificationHeader"></a>

View file

@ -31,20 +31,22 @@ func newTestClient(t *testing.T) *testClient {
func signToken(t *testing.T, token *PToken, c *testClient) { func signToken(t *testing.T, token *PToken, c *testClient) {
require.NotNil(t, token) require.NotNil(t, token)
token.SetPublicKeys(&c.PublicKey)
signH, err := c.Sign(token.Header.PublicKey) signH, err := c.Sign(token.Header.PublicKey)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, signH) require.NotNil(t, signH)
// data is not yet signed // data is not yet signed
require.False(t, token.Verify(&c.PublicKey)) keys := UnmarshalPublicKeys(&token.Token)
require.False(t, token.Verify(keys...))
signT, err := c.Sign(token.verificationData()) signT, err := c.Sign(token.verificationData())
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, signT) require.NotNil(t, signT)
token.AddSignatures(signH, signT) token.AddSignatures(signH, signT)
require.True(t, token.Verify(&c.PublicKey)) require.True(t, token.Verify(keys...))
} }
func TestTokenStore(t *testing.T) { func TestTokenStore(t *testing.T) {

View file

@ -6,6 +6,7 @@ import (
"sync" "sync"
crypto "github.com/nspcc-dev/neofs-crypto" crypto "github.com/nspcc-dev/neofs-crypto"
"github.com/nspcc-dev/neofs-proto/chain"
"github.com/nspcc-dev/neofs-proto/internal" "github.com/nspcc-dev/neofs-proto/internal"
"github.com/nspcc-dev/neofs-proto/refs" "github.com/nspcc-dev/neofs-proto/refs"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -111,11 +112,24 @@ func (m *Token) Sign(key *ecdsa.PrivateKey) error {
return nil return nil
} }
// SetPublicKeys sets owner's public keys to the token
func (m *Token) SetPublicKeys(keys... *ecdsa.PublicKey) {
m.PublicKeys = m.PublicKeys[:0]
for i := range keys {
m.PublicKeys = append(m.PublicKeys, crypto.MarshalPublicKey(keys[i]))
}
}
// Verify checks if token is correct and signed. // Verify checks if token is correct and signed.
func (m *Token) Verify(keys ...*ecdsa.PublicKey) bool { func (m *Token) Verify(keys ...*ecdsa.PublicKey) bool {
if m.FirstEpoch > m.LastEpoch { if m.FirstEpoch > m.LastEpoch {
return false return false
} }
ownerFromKeys := chain.KeysToAddress(keys...)
if m.OwnerID.String() != ownerFromKeys {
return false
}
for i := range keys { for i := range keys {
if m.Header.Verify(keys[i]) && crypto.Verify(keys[i], m.verificationData(), m.Signature) == nil { if m.Header.Verify(keys[i]) && crypto.Verify(keys[i], m.verificationData(), m.Signature) == nil {
return true return true
@ -156,3 +170,12 @@ func (m *VerificationHeader) Verify(keys ...*ecdsa.PublicKey) bool {
} }
return false return false
} }
// UnmarshalPublicKeys returns unmarshal public keys from the token
func UnmarshalPublicKeys(t *Token) []*ecdsa.PublicKey {
r := make([]*ecdsa.PublicKey, 0, len(t.PublicKeys))
for i := range t.PublicKeys {
r = append(r, crypto.UnmarshalPublicKey(t.PublicKeys[i]))
}
return r
}

Binary file not shown.

View file

@ -29,4 +29,6 @@ message Token {
bytes Signature = 6; bytes Signature = 6;
// ID is a token identifier. valid UUIDv4 represented in bytes // ID is a token identifier. valid UUIDv4 represented in bytes
bytes ID = 7 [(gogoproto.customtype) = "TokenID", (gogoproto.nullable) = false]; bytes ID = 7 [(gogoproto.customtype) = "TokenID", (gogoproto.nullable) = false];
// PublicKeys associated with owner
repeated bytes PublicKeys = 8;
} }