forked from TrueCloudLab/frostfs-sdk-go
*: demand RFC6979 signer where appropriate
It's needed for container operations, therefore default ones for client and pool have to be of this type as well. And it's easier to check for it before usage. Fixes #209. Signed-off-by: Roman Khimov <roman@nspcc.ru>
This commit is contained in:
parent
2e18c3c16d
commit
e99e9537a2
7 changed files with 78 additions and 27 deletions
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
v2accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting"
|
||||
|
@ -49,11 +50,19 @@ type Client struct {
|
|||
server neoFSAPIServer
|
||||
}
|
||||
|
||||
var errNonNeoSigner = fmt.Errorf("%w: expected ECDSA_DETERMINISTIC_SHA256 scheme", neofscrypto.ErrIncorrectSigner)
|
||||
|
||||
// New creates an instance of Client initialized with the given parameters.
|
||||
//
|
||||
// See docs of [PrmInit] methods for details. See also [Client.Dial]/[Client.Close].
|
||||
//
|
||||
// Returned errors:
|
||||
// - [neofscrypto.ErrIncorrectSigner]
|
||||
func New(prm PrmInit) (*Client, error) {
|
||||
var c = new(Client)
|
||||
if prm.signer != nil && prm.signer.Scheme() != neofscrypto.ECDSA_DETERMINISTIC_SHA256 {
|
||||
return nil, errNonNeoSigner
|
||||
}
|
||||
c.prm = prm
|
||||
return c, nil
|
||||
}
|
||||
|
|
|
@ -406,6 +406,7 @@ func (x *PrmContainerDelete) WithinSession(tok session.Container) {
|
|||
//
|
||||
// Return errors:
|
||||
// - [ErrMissingContainer]
|
||||
// - [neofscrypto.ErrIncorrectSigner]
|
||||
//
|
||||
// Reflects all internal errors in second return value (transport problems, response processing, etc.).
|
||||
func (c *Client) ContainerDelete(ctx context.Context, prm PrmContainerDelete) error {
|
||||
|
@ -429,6 +430,9 @@ func (c *Client) ContainerDelete(ctx context.Context, prm PrmContainerDelete) er
|
|||
signer = c.defaultSigner()
|
||||
}
|
||||
|
||||
if signer.Scheme() != neofscrypto.ECDSA_DETERMINISTIC_SHA256 {
|
||||
return errNonNeoSigner
|
||||
}
|
||||
err := sig.Calculate(signer, data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("calculate signature: %w", err)
|
||||
|
@ -622,6 +626,7 @@ func (x *PrmContainerSetEACL) WithinSession(s session.Container) {
|
|||
// Return errors:
|
||||
// - [ErrMissingEACL]
|
||||
// - [ErrMissingEACLContainer]
|
||||
// - [neofscrypto.ErrIncorrectSigner]
|
||||
//
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
func (c *Client) ContainerSetEACL(ctx context.Context, prm PrmContainerSetEACL) error {
|
||||
|
@ -645,6 +650,10 @@ func (c *Client) ContainerSetEACL(ctx context.Context, prm PrmContainerSetEACL)
|
|||
signer = c.defaultSigner()
|
||||
}
|
||||
|
||||
if signer.Scheme() != neofscrypto.ECDSA_DETERMINISTIC_SHA256 {
|
||||
return errNonNeoSigner
|
||||
}
|
||||
|
||||
err := sig.Calculate(signer, eaclV2.StableMarshal(nil))
|
||||
if err != nil {
|
||||
return fmt.Errorf("calculate signature: %w", err)
|
||||
|
|
|
@ -481,7 +481,13 @@ func ReadDomain(cnr Container) (res Domain) {
|
|||
// can be used.
|
||||
//
|
||||
// See also VerifySignature.
|
||||
//
|
||||
// Returned errors:
|
||||
// - [neofscrypto.ErrIncorrectSigner]
|
||||
func CalculateSignature(dst *neofscrypto.Signature, cnr Container, signer neofscrypto.Signer) error {
|
||||
if signer.Scheme() != neofscrypto.ECDSA_DETERMINISTIC_SHA256 {
|
||||
return fmt.Errorf("%w: expected ECDSA_DETERMINISTIC_SHA256 scheme", neofscrypto.ErrIncorrectSigner)
|
||||
}
|
||||
return dst.Calculate(signer, cnr.Marshal())
|
||||
}
|
||||
|
||||
|
|
|
@ -336,6 +336,7 @@ func TestCalculateSignature(t *testing.T) {
|
|||
|
||||
var sig neofscrypto.Signature
|
||||
|
||||
require.Error(t, container.CalculateSignature(&sig, val, test.RandomSigner(t)))
|
||||
require.NoError(t, container.CalculateSignature(&sig, val, test.RandomSignerRFC6979(t)))
|
||||
|
||||
var msg refs.Signature
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
package neofscrypto
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
)
|
||||
|
||||
// ErrIncorrectSigner is returned from function when the signer passed to it
|
||||
// is incompatible with the function requirements. This variable is intended
|
||||
// to be used as documentation and for [errors.Is] purposes and MUST NOT be
|
||||
// changed.
|
||||
var ErrIncorrectSigner = errors.New("incorrect signer")
|
||||
|
||||
// Scheme represents digital signature algorithm with fixed cryptographic hash function.
|
||||
//
|
||||
// Negative values are reserved and depend on context (e.g. unsupported scheme).
|
||||
|
|
|
@ -1535,10 +1535,16 @@ const (
|
|||
)
|
||||
|
||||
// NewPool creates connection pool using parameters.
|
||||
//
|
||||
// Returned errors:
|
||||
// - [neofscrypto.ErrIncorrectSigner]
|
||||
func NewPool(options InitParameters) (*Pool, error) {
|
||||
if options.signer == nil {
|
||||
return nil, fmt.Errorf("missed required parameter 'Signer'")
|
||||
}
|
||||
if options.signer.Scheme() != neofscrypto.ECDSA_DETERMINISTIC_SHA256 {
|
||||
return nil, fmt.Errorf("%w: expected ECDSA_DETERMINISTIC_SHA256 scheme", neofscrypto.ErrIncorrectSigner)
|
||||
}
|
||||
|
||||
nodesParams, err := adjustNodeParams(options.nodeParams)
|
||||
if err != nil {
|
||||
|
|
|
@ -25,7 +25,7 @@ func TestBuildPoolClientFailed(t *testing.T) {
|
|||
return nil, errors.New("oops")
|
||||
}
|
||||
mockClientBuilder2 := func(addr string) (client, error) {
|
||||
mockCli := newMockClient(addr, test.RandomSigner(t))
|
||||
mockCli := newMockClient(addr, test.RandomSignerRFC6979(t))
|
||||
mockCli.errOnDial()
|
||||
return mockCli, nil
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ func TestBuildPoolClientFailed(t *testing.T) {
|
|||
} {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
opts := InitParameters{
|
||||
signer: test.RandomSigner(t),
|
||||
signer: test.RandomSignerRFC6979(t),
|
||||
nodeParams: []NodeParam{{1, "peer0", 1}},
|
||||
}
|
||||
opts.setClientBuilder(b)
|
||||
|
@ -51,13 +51,13 @@ func TestBuildPoolClientFailed(t *testing.T) {
|
|||
|
||||
func TestBuildPoolCreateSessionFailed(t *testing.T) {
|
||||
clientMockBuilder := func(addr string) (client, error) {
|
||||
mockCli := newMockClient(addr, test.RandomSigner(t))
|
||||
mockCli := newMockClient(addr, test.RandomSignerRFC6979(t))
|
||||
mockCli.errOnCreateSession()
|
||||
return mockCli, nil
|
||||
}
|
||||
|
||||
opts := InitParameters{
|
||||
signer: test.RandomSigner(t),
|
||||
signer: test.RandomSignerRFC6979(t),
|
||||
nodeParams: []NodeParam{{1, "peer0", 1}},
|
||||
}
|
||||
opts.setClientBuilder(clientMockBuilder)
|
||||
|
@ -76,7 +76,7 @@ func TestBuildPoolOneNodeFailed(t *testing.T) {
|
|||
|
||||
var clientKeys []neofscrypto.Signer
|
||||
mockClientBuilder := func(addr string) (client, error) {
|
||||
key := test.RandomSigner(t)
|
||||
key := test.RandomSignerRFC6979(t)
|
||||
clientKeys = append(clientKeys, key)
|
||||
|
||||
if addr == nodes[0].address {
|
||||
|
@ -91,7 +91,7 @@ func TestBuildPoolOneNodeFailed(t *testing.T) {
|
|||
log, err := zap.NewProduction()
|
||||
require.NoError(t, err)
|
||||
opts := InitParameters{
|
||||
signer: test.RandomSigner(t),
|
||||
signer: test.RandomSignerRFC6979(t),
|
||||
clientRebalanceInterval: 1000 * time.Millisecond,
|
||||
logger: log,
|
||||
nodeParams: nodes,
|
||||
|
@ -118,6 +118,19 @@ func TestBuildPoolOneNodeFailed(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBuildPoolZeroNodes(t *testing.T) {
|
||||
opts := InitParameters{
|
||||
signer: test.RandomSignerRFC6979(t),
|
||||
}
|
||||
_, err := NewPool(opts)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestBuildPoolNoSigner(t *testing.T) {
|
||||
_, err := NewPool(InitParameters{})
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestBuildPoolWrongSigner(t *testing.T) {
|
||||
opts := InitParameters{
|
||||
signer: test.RandomSigner(t),
|
||||
}
|
||||
|
@ -126,13 +139,13 @@ func TestBuildPoolZeroNodes(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestOneNode(t *testing.T) {
|
||||
key1 := test.RandomSigner(t)
|
||||
key1 := test.RandomSignerRFC6979(t)
|
||||
mockClientBuilder := func(addr string) (client, error) {
|
||||
return newMockClient(addr, key1), nil
|
||||
}
|
||||
|
||||
opts := InitParameters{
|
||||
signer: test.RandomSigner(t),
|
||||
signer: test.RandomSignerRFC6979(t),
|
||||
nodeParams: []NodeParam{{1, "peer0", 1}},
|
||||
}
|
||||
opts.setClientBuilder(mockClientBuilder)
|
||||
|
@ -152,13 +165,13 @@ func TestOneNode(t *testing.T) {
|
|||
func TestTwoNodes(t *testing.T) {
|
||||
var clientKeys []neofscrypto.Signer
|
||||
mockClientBuilder := func(addr string) (client, error) {
|
||||
key := test.RandomSigner(t)
|
||||
key := test.RandomSignerRFC6979(t)
|
||||
clientKeys = append(clientKeys, key)
|
||||
return newMockClient(addr, key), nil
|
||||
}
|
||||
|
||||
opts := InitParameters{
|
||||
signer: test.RandomSigner(t),
|
||||
signer: test.RandomSignerRFC6979(t),
|
||||
nodeParams: []NodeParam{
|
||||
{1, "peer0", 1},
|
||||
{1, "peer1", 1},
|
||||
|
@ -196,7 +209,7 @@ func TestOneOfTwoFailed(t *testing.T) {
|
|||
|
||||
var clientKeys []neofscrypto.Signer
|
||||
mockClientBuilder := func(addr string) (client, error) {
|
||||
key := test.RandomSigner(t)
|
||||
key := test.RandomSignerRFC6979(t)
|
||||
clientKeys = append(clientKeys, key)
|
||||
|
||||
if addr == nodes[0].address {
|
||||
|
@ -210,7 +223,7 @@ func TestOneOfTwoFailed(t *testing.T) {
|
|||
}
|
||||
|
||||
opts := InitParameters{
|
||||
signer: test.RandomSigner(t),
|
||||
signer: test.RandomSignerRFC6979(t),
|
||||
nodeParams: nodes,
|
||||
clientRebalanceInterval: 200 * time.Millisecond,
|
||||
}
|
||||
|
@ -237,7 +250,7 @@ func TestOneOfTwoFailed(t *testing.T) {
|
|||
func TestTwoFailed(t *testing.T) {
|
||||
var clientKeys []neofscrypto.Signer
|
||||
mockClientBuilder := func(addr string) (client, error) {
|
||||
key := test.RandomSigner(t)
|
||||
key := test.RandomSignerRFC6979(t)
|
||||
clientKeys = append(clientKeys, key)
|
||||
mockCli := newMockClient(addr, key)
|
||||
mockCli.errOnEndpointInfo()
|
||||
|
@ -245,7 +258,7 @@ func TestTwoFailed(t *testing.T) {
|
|||
}
|
||||
|
||||
opts := InitParameters{
|
||||
signer: test.RandomSigner(t),
|
||||
signer: test.RandomSignerRFC6979(t),
|
||||
nodeParams: []NodeParam{
|
||||
{1, "peer0", 1},
|
||||
{1, "peer1", 1},
|
||||
|
@ -269,7 +282,7 @@ func TestTwoFailed(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSessionCache(t *testing.T) {
|
||||
key := test.RandomSigner(t)
|
||||
key := test.RandomSignerRFC6979(t)
|
||||
|
||||
mockClientBuilder := func(addr string) (client, error) {
|
||||
mockCli := newMockClient(addr, key)
|
||||
|
@ -278,7 +291,7 @@ func TestSessionCache(t *testing.T) {
|
|||
}
|
||||
|
||||
opts := InitParameters{
|
||||
signer: test.RandomSigner(t),
|
||||
signer: test.RandomSignerRFC6979(t),
|
||||
nodeParams: []NodeParam{
|
||||
{1, "peer0", 1},
|
||||
},
|
||||
|
@ -335,7 +348,7 @@ func TestPriority(t *testing.T) {
|
|||
|
||||
var clientKeys []neofscrypto.Signer
|
||||
mockClientBuilder := func(addr string) (client, error) {
|
||||
key := test.RandomSigner(t)
|
||||
key := test.RandomSignerRFC6979(t)
|
||||
clientKeys = append(clientKeys, key)
|
||||
|
||||
if addr == nodes[0].address {
|
||||
|
@ -348,7 +361,7 @@ func TestPriority(t *testing.T) {
|
|||
}
|
||||
|
||||
opts := InitParameters{
|
||||
signer: test.RandomSigner(t),
|
||||
signer: test.RandomSignerRFC6979(t),
|
||||
nodeParams: nodes,
|
||||
clientRebalanceInterval: 1500 * time.Millisecond,
|
||||
}
|
||||
|
@ -385,14 +398,14 @@ func TestPriority(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSessionCacheWithKey(t *testing.T) {
|
||||
key := test.RandomSigner(t)
|
||||
key := test.RandomSignerRFC6979(t)
|
||||
|
||||
mockClientBuilder := func(addr string) (client, error) {
|
||||
return newMockClient(addr, key), nil
|
||||
}
|
||||
|
||||
opts := InitParameters{
|
||||
signer: test.RandomSigner(t),
|
||||
signer: test.RandomSignerRFC6979(t),
|
||||
nodeParams: []NodeParam{
|
||||
{1, "peer0", 1},
|
||||
},
|
||||
|
@ -416,7 +429,7 @@ func TestSessionCacheWithKey(t *testing.T) {
|
|||
|
||||
var prm PrmObjectDelete
|
||||
prm.SetAddress(oid.Address{})
|
||||
anonKey := test.RandomSigner(t)
|
||||
anonKey := test.RandomSignerRFC6979(t)
|
||||
prm.UseSigner(anonKey)
|
||||
|
||||
err = pool.DeleteObject(ctx, prm)
|
||||
|
@ -427,12 +440,12 @@ func TestSessionCacheWithKey(t *testing.T) {
|
|||
|
||||
func TestSessionTokenOwner(t *testing.T) {
|
||||
mockClientBuilder := func(addr string) (client, error) {
|
||||
key := test.RandomSigner(t)
|
||||
key := test.RandomSignerRFC6979(t)
|
||||
return newMockClient(addr, key), nil
|
||||
}
|
||||
|
||||
opts := InitParameters{
|
||||
signer: test.RandomSigner(t),
|
||||
signer: test.RandomSignerRFC6979(t),
|
||||
nodeParams: []NodeParam{
|
||||
{1, "peer0", 1},
|
||||
},
|
||||
|
@ -448,7 +461,7 @@ func TestSessionTokenOwner(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
t.Cleanup(p.Close)
|
||||
|
||||
anonKey := test.RandomSigner(t)
|
||||
anonKey := test.RandomSignerRFC6979(t)
|
||||
var anonOwner user.ID
|
||||
require.NoError(t, user.IDFromSigner(&anonOwner, anonKey))
|
||||
|
||||
|
@ -473,7 +486,7 @@ func TestSessionTokenOwner(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestWaitPresence(t *testing.T) {
|
||||
mockCli := newMockClient("", test.RandomSigner(t))
|
||||
mockCli := newMockClient("", test.RandomSignerRFC6979(t))
|
||||
|
||||
t.Run("context canceled", func(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
@ -612,7 +625,7 @@ func TestSwitchAfterErrorThreshold(t *testing.T) {
|
|||
|
||||
var clientKeys []neofscrypto.Signer
|
||||
mockClientBuilder := func(addr string) (client, error) {
|
||||
key := test.RandomSigner(t)
|
||||
key := test.RandomSignerRFC6979(t)
|
||||
clientKeys = append(clientKeys, key)
|
||||
|
||||
if addr == nodes[0].address {
|
||||
|
@ -626,7 +639,7 @@ func TestSwitchAfterErrorThreshold(t *testing.T) {
|
|||
}
|
||||
|
||||
opts := InitParameters{
|
||||
signer: test.RandomSigner(t),
|
||||
signer: test.RandomSignerRFC6979(t),
|
||||
nodeParams: nodes,
|
||||
clientRebalanceInterval: 30 * time.Second,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue