forked from TrueCloudLab/frostfs-sdk-go
[#103] owner: remove NEO3Wallet type
Allow to use public keys and N3 wallet accounts instead. Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
f83ff628fb
commit
596774ce5b
13 changed files with 103 additions and 144 deletions
|
@ -82,13 +82,7 @@ func (c *Client) PutContainer(ctx context.Context, cnr *container.Container, opt
|
|||
|
||||
// if container owner is not set, then use client key as owner
|
||||
if cnr.OwnerID() == nil {
|
||||
w, err := owner.NEO3WalletFromPublicKey(&callOptions.key.PublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ownerID := new(owner.ID)
|
||||
ownerID.SetNeo3Wallet(w)
|
||||
ownerID := owner.NewIDFromPublicKey(&callOptions.key.PublicKey)
|
||||
|
||||
cnr.SetOwnerID(ownerID)
|
||||
}
|
||||
|
@ -270,13 +264,7 @@ func (c *Client) ListContainers(ctx context.Context, ownerID *owner.ID, opts ...
|
|||
}
|
||||
|
||||
if ownerID == nil {
|
||||
w, err := owner.NEO3WalletFromPublicKey(&callOptions.key.PublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ownerID = new(owner.ID)
|
||||
ownerID.SetNeo3Wallet(w)
|
||||
ownerID = owner.NewIDFromPublicKey(&callOptions.key.PublicKey)
|
||||
}
|
||||
|
||||
reqBody := new(v2container.ListRequestBody)
|
||||
|
|
|
@ -50,13 +50,7 @@ func (c *Client) CreateSession(ctx context.Context, expiration uint64, opts ...C
|
|||
opts[i](callOptions)
|
||||
}
|
||||
|
||||
w, err := owner.NEO3WalletFromPublicKey(&callOptions.key.PublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ownerID := new(owner.ID)
|
||||
ownerID.SetNeo3Wallet(w)
|
||||
ownerID := owner.NewIDFromPublicKey(&callOptions.key.PublicKey)
|
||||
|
||||
reqBody := new(v2session.CreateRequestBody)
|
||||
reqBody.SetOwnerID(ownerID.ToV2())
|
||||
|
@ -66,7 +60,7 @@ func (c *Client) CreateSession(ctx context.Context, expiration uint64, opts ...C
|
|||
req.SetBody(reqBody)
|
||||
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
|
||||
|
||||
err = v2signature.SignServiceMessage(callOptions.key, req)
|
||||
err := v2signature.SignServiceMessage(callOptions.key, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/acl"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||
|
@ -61,13 +63,13 @@ func WithOwnerID(id *owner.ID) Option {
|
|||
}
|
||||
}
|
||||
|
||||
func WithNEO3Wallet(w *owner.NEO3Wallet) Option {
|
||||
func WithOwnerPublicKey(pub *ecdsa.PublicKey) Option {
|
||||
return func(option *containerOptions) {
|
||||
if option.owner == nil {
|
||||
option.owner = new(owner.ID)
|
||||
}
|
||||
|
||||
option.owner.SetNeo3Wallet(w)
|
||||
option.owner.SetPublicKey(pub)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
34
owner/convert_test.go
Normal file
34
owner/convert_test.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package owner
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNEO3WalletFromPublicKey(t *testing.T) {
|
||||
rawPub, _ := hex.DecodeString("0369b7b6c49fb937f3de52af189b91069767679c2739798d85f2ed69c079940680")
|
||||
x, y := elliptic.UnmarshalCompressed(elliptic.P256(), rawPub)
|
||||
require.True(t, x != nil && y != nil)
|
||||
|
||||
expected := "35ee628f21922d7308f1bd71f03a0d8ba89c4e7372fca1442c"
|
||||
actual := PublicKeyToIDBytes(&ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y})
|
||||
require.Equal(t, expected, hex.EncodeToString(actual))
|
||||
}
|
||||
|
||||
func TestPublicKeyToBytes(t *testing.T) {
|
||||
p, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
expected, err := base58.Decode(p.PublicKey().Address())
|
||||
require.NoError(t, err)
|
||||
|
||||
actual := PublicKeyToIDBytes((*ecdsa.PublicKey)(p.PublicKey()))
|
||||
require.Equal(t, expected, actual)
|
||||
require.Equal(t, NEO3WalletSize, len(actual))
|
||||
}
|
39
owner/id.go
39
owner/id.go
|
@ -2,12 +2,15 @@ package owner
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
)
|
||||
|
||||
|
@ -16,6 +19,12 @@ type ID refs.OwnerID
|
|||
|
||||
var errInvalidIDString = errors.New("incorrect format of the string owner ID")
|
||||
|
||||
// ErrEmptyPublicKey when public key passed to Verify method is nil.
|
||||
var ErrEmptyPublicKey = errors.New("empty public key")
|
||||
|
||||
// NEO3WalletSize contains size of neo3 wallet.
|
||||
const NEO3WalletSize = 25
|
||||
|
||||
// NewIDFromV2 wraps v2 OwnerID message to ID.
|
||||
//
|
||||
// Nil refs.OwnerID converts to nil.
|
||||
|
@ -33,9 +42,9 @@ func NewID() *ID {
|
|||
return NewIDFromV2(new(refs.OwnerID))
|
||||
}
|
||||
|
||||
// SetNeo3Wallet sets owner identifier value to NEO3 wallet address.
|
||||
func (id *ID) SetNeo3Wallet(v *NEO3Wallet) {
|
||||
(*refs.OwnerID)(id).SetValue(v.Bytes())
|
||||
// SetPublicKey sets owner identifier value to the provided NEO3 public key.
|
||||
func (id *ID) SetPublicKey(pub *ecdsa.PublicKey) {
|
||||
(*refs.OwnerID)(id).SetValue(PublicKeyToIDBytes(pub))
|
||||
}
|
||||
|
||||
// ToV2 returns the v2 owner ID message.
|
||||
|
@ -60,14 +69,20 @@ func (id *ID) Equal(id2 *ID) bool {
|
|||
)
|
||||
}
|
||||
|
||||
// NewIDFromNeo3Wallet creates new owner identity from 25-byte neo wallet.
|
||||
func NewIDFromNeo3Wallet(v *NEO3Wallet) *ID {
|
||||
// NewIDFromPublicKey creates new owner identity from ECDSA public key.
|
||||
func NewIDFromPublicKey(pub *ecdsa.PublicKey) *ID {
|
||||
id := NewID()
|
||||
id.SetNeo3Wallet(v)
|
||||
id.SetPublicKey(pub)
|
||||
|
||||
return id
|
||||
}
|
||||
|
||||
// NewIDFromPublicKey creates new owner identity from N3 wallet account.
|
||||
func NewIDFromN3Account(acc *wallet.Account) *ID {
|
||||
return NewIDFromPublicKey(
|
||||
(*ecdsa.PublicKey)(acc.PrivateKey().PublicKey()))
|
||||
}
|
||||
|
||||
// Parse converts base58 string representation into ID.
|
||||
func (id *ID) Parse(s string) error {
|
||||
data, err := base58.Decode(s)
|
||||
|
@ -123,3 +138,15 @@ func (id *ID) MarshalJSON() ([]byte, error) {
|
|||
func (id *ID) UnmarshalJSON(data []byte) error {
|
||||
return (*refs.OwnerID)(id).UnmarshalJSON(data)
|
||||
}
|
||||
|
||||
// PublicKeyToIDBytes converts public key to a byte slice of NEO3WalletSize length.
|
||||
// It is similar to decoding a NEO3 address but is inlined to skip base58 encoding-decoding step
|
||||
// make it clear that no errors can occur.
|
||||
func PublicKeyToIDBytes(pub *ecdsa.PublicKey) []byte {
|
||||
sh := (*keys.PublicKey)(pub).GetScriptHash()
|
||||
b := make([]byte, NEO3WalletSize)
|
||||
b[0] = address.Prefix
|
||||
copy(b[1:], sh.BytesBE())
|
||||
copy(b[21:], hash.Checksum(b[:21]))
|
||||
return b
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/mr-tron/base58"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
. "github.com/nspcc-dev/neofs-sdk-go/owner"
|
||||
ownertest "github.com/nspcc-dev/neofs-sdk-go/owner/test"
|
||||
|
@ -49,26 +50,28 @@ func TestID_Valid(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestNewIDFromNeo3Wallet(t *testing.T) {
|
||||
func TestNewIDFromN3Account(t *testing.T) {
|
||||
acc, err := wallet.NewAccount()
|
||||
require.NoError(t, err)
|
||||
|
||||
id := NewIDFromN3Account(acc)
|
||||
require.Equal(t, id.String(), acc.Address)
|
||||
}
|
||||
|
||||
func TestNewIDFromPublicKey(t *testing.T) {
|
||||
p, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
wallet, err := NEO3WalletFromPublicKey((*ecdsa.PublicKey)(p.PublicKey()))
|
||||
require.NoError(t, err)
|
||||
|
||||
id := NewIDFromNeo3Wallet(wallet)
|
||||
require.Equal(t, id.ToV2().GetValue(), wallet.Bytes())
|
||||
id := NewIDFromPublicKey((*ecdsa.PublicKey)(p.PublicKey()))
|
||||
require.Equal(t, id.String(), p.Address())
|
||||
}
|
||||
|
||||
func TestID_Parse(t *testing.T) {
|
||||
t.Run("should parse successful", func(t *testing.T) {
|
||||
p, err := keys.NewPrivateKey()
|
||||
acc, err := wallet.NewAccount()
|
||||
require.NoError(t, err)
|
||||
|
||||
wallet, err := NEO3WalletFromPublicKey((*ecdsa.PublicKey)(p.PublicKey()))
|
||||
require.NoError(t, err)
|
||||
|
||||
eid := NewIDFromNeo3Wallet(wallet)
|
||||
eid := NewIDFromN3Account(acc)
|
||||
aid := NewID()
|
||||
|
||||
require.NoError(t, aid.Parse(eid.String()))
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
package owner
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
)
|
||||
|
||||
// NEO3Wallet represents NEO3 wallet address.
|
||||
type NEO3Wallet [NEO3WalletSize]byte
|
||||
|
||||
// NEO3WalletSize contains size of neo3 wallet.
|
||||
const NEO3WalletSize = 25
|
||||
|
||||
// ErrEmptyPublicKey when PK passed to Verify method is nil.
|
||||
var ErrEmptyPublicKey = errors.New("empty public key")
|
||||
|
||||
// NEO3WalletFromPublicKey converts public key to NEO3 wallet address.
|
||||
func NEO3WalletFromPublicKey(key *ecdsa.PublicKey) (*NEO3Wallet, error) {
|
||||
if key == nil {
|
||||
return nil, ErrEmptyPublicKey
|
||||
}
|
||||
|
||||
neoPublicKey := (*keys.PublicKey)(key)
|
||||
|
||||
d, err := base58.Decode(neoPublicKey.Address())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't decode neo3 address from key: %w", err)
|
||||
}
|
||||
|
||||
w := new(NEO3Wallet)
|
||||
copy(w.Bytes(), d)
|
||||
|
||||
return w, nil
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer.
|
||||
func (w *NEO3Wallet) String() string {
|
||||
if w != nil {
|
||||
return base58.Encode(w[:])
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// Bytes returns slice of NEO3 wallet address bytes.
|
||||
func (w *NEO3Wallet) Bytes() []byte {
|
||||
if w != nil {
|
||||
return w[:]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package owner
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNEO3WalletFromPublicKey(t *testing.T) {
|
||||
rawPub, _ := hex.DecodeString("0369b7b6c49fb937f3de52af189b91069767679c2739798d85f2ed69c079940680")
|
||||
x, y := elliptic.UnmarshalCompressed(elliptic.P256(), rawPub)
|
||||
require.True(t, x != nil && y != nil)
|
||||
|
||||
expected := "35ee628f21922d7308f1bd71f03a0d8ba89c4e7372fca1442c"
|
||||
w, err := NEO3WalletFromPublicKey(&ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expected, hex.EncodeToString(w[:]))
|
||||
}
|
13
pool/pool.go
13
pool/pool.go
|
@ -254,17 +254,12 @@ type innerPool struct {
|
|||
}
|
||||
|
||||
func newPool(ctx context.Context, options *BuilderOptions) (Pool, error) {
|
||||
wallet, err := owner.NEO3WalletFromPublicKey(&options.Key.PublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cache, err := NewCache()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't create cache: %w", err)
|
||||
}
|
||||
|
||||
ownerID := owner.NewIDFromNeo3Wallet(wallet)
|
||||
ownerID := owner.NewIDFromPublicKey(&options.Key.PublicKey)
|
||||
|
||||
inner := make([]*innerPool, len(options.nodesParams))
|
||||
var atLeastOneHealthy bool
|
||||
|
@ -498,11 +493,7 @@ func (p *pool) conn(ctx context.Context, cfg *callConfig) (*clientPack, []client
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
wallet, err := owner.NEO3WalletFromPublicKey(&key.PublicKey)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
ownerID := owner.NewIDFromNeo3Wallet(wallet)
|
||||
ownerID := owner.NewIDFromPublicKey(&key.PublicKey)
|
||||
sessionToken = sessionTokenForOwner(ownerID, cliRes)
|
||||
|
||||
_ = p.cache.Put(cacheKey, sessionToken)
|
||||
|
|
|
@ -511,9 +511,7 @@ func TestSessionTokenOwner(t *testing.T) {
|
|||
require.True(t, ok)
|
||||
|
||||
anonKey := newPrivateKey(t)
|
||||
wallet, err := owner.NEO3WalletFromPublicKey(&anonKey.PublicKey)
|
||||
require.NoError(t, err)
|
||||
anonOwner := owner.NewIDFromNeo3Wallet(wallet)
|
||||
anonOwner := owner.NewIDFromPublicKey(&anonKey.PublicKey)
|
||||
|
||||
cfg := cfgFromOpts(WithKey(anonKey), useDefaultSession())
|
||||
cp, _, err := p.conn(ctx, cfg)
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package sessiontest
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
|
@ -31,11 +33,13 @@ func Token() *session.Token {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
w := new(owner.NEO3Wallet)
|
||||
rand.Read(w.Bytes())
|
||||
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ownerID := owner.NewID()
|
||||
ownerID.SetNeo3Wallet(w)
|
||||
ownerID.SetPublicKey(&priv.PublicKey)
|
||||
|
||||
keyBin := p.PublicKey().Bytes()
|
||||
|
||||
|
|
|
@ -91,12 +91,10 @@ func (b *BearerToken) SignToken(key *ecdsa.PrivateKey) error {
|
|||
// nil if token is not signed.
|
||||
func (b *BearerToken) Issuer() *owner.ID {
|
||||
pub, _ := keys.NewPublicKeyFromBytes(b.token.GetSignature().GetKey(), elliptic.P256())
|
||||
wallet, err := owner.NEO3WalletFromPublicKey((*ecdsa.PublicKey)(pub))
|
||||
if err != nil {
|
||||
if pub == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return owner.NewIDFromNeo3Wallet(wallet)
|
||||
return owner.NewIDFromPublicKey((*ecdsa.PublicKey)(pub))
|
||||
}
|
||||
|
||||
// NewBearerToken creates and initializes blank BearerToken.
|
||||
|
|
|
@ -23,10 +23,7 @@ func TestBearerToken_Issuer(t *testing.T) {
|
|||
p, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
wallet, err := owner.NEO3WalletFromPublicKey((*ecdsa.PublicKey)(p.PublicKey()))
|
||||
require.NoError(t, err)
|
||||
|
||||
ownerID := owner.NewIDFromNeo3Wallet(wallet)
|
||||
ownerID := owner.NewIDFromPublicKey((*ecdsa.PublicKey)(p.PublicKey()))
|
||||
|
||||
bearerToken.SetEACLTable(eacl.NewTable())
|
||||
require.NoError(t, bearerToken.SignToken(&p.PrivateKey))
|
||||
|
|
Loading…
Reference in a new issue