forked from TrueCloudLab/frostfs-api-go
Merge pull request #36 from nspcc-dev/public-keys-in-token
Public keys in token
This commit is contained in:
commit
038f934da5
5 changed files with 30 additions and 2 deletions
|
@ -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>
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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.
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue