forked from TrueCloudLab/frostfs-sdk-go
[#150] util/signature: Simplify public interface
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
1c7dd03cf5
commit
d716765c1a
7 changed files with 68 additions and 103 deletions
|
@ -86,13 +86,13 @@ func (c *Client) ContainerPut(ctx context.Context, prm PrmContainerPut) (*ResCon
|
||||||
// sign container
|
// sign container
|
||||||
signWrapper := v2signature.StableMarshalerWrapper{SM: reqBody.GetContainer()}
|
signWrapper := v2signature.StableMarshalerWrapper{SM: reqBody.GetContainer()}
|
||||||
|
|
||||||
err := sigutil.SignDataWithHandler(c.opts.key, signWrapper, func(sig *signature.Signature) {
|
sig, err := sigutil.SignData(c.opts.key, signWrapper, sigutil.SignWithRFC6979())
|
||||||
reqBody.SetSignature(sig.ToV2())
|
|
||||||
}, sigutil.SignWithRFC6979())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reqBody.SetSignature(sig.ToV2())
|
||||||
|
|
||||||
// form meta header
|
// form meta header
|
||||||
var meta v2session.RequestMetaHeader
|
var meta v2session.RequestMetaHeader
|
||||||
meta.SetSessionToken(prm.cnr.SessionToken().ToV2())
|
meta.SetSessionToken(prm.cnr.SessionToken().ToV2())
|
||||||
|
@ -393,19 +393,16 @@ func (c *Client) ContainerDelete(ctx context.Context, prm PrmContainerDelete) (*
|
||||||
reqBody := new(v2container.DeleteRequestBody)
|
reqBody := new(v2container.DeleteRequestBody)
|
||||||
reqBody.SetContainerID(prm.id.ToV2())
|
reqBody.SetContainerID(prm.id.ToV2())
|
||||||
|
|
||||||
|
signWrapper := delContainerSignWrapper{body: reqBody}
|
||||||
|
|
||||||
// sign container
|
// sign container
|
||||||
err := sigutil.SignDataWithHandler(c.opts.key,
|
sig, err := sigutil.SignData(c.opts.key, signWrapper, sigutil.SignWithRFC6979())
|
||||||
delContainerSignWrapper{
|
|
||||||
body: reqBody,
|
|
||||||
},
|
|
||||||
func(sig *signature.Signature) {
|
|
||||||
reqBody.SetSignature(sig.ToV2())
|
|
||||||
},
|
|
||||||
sigutil.SignWithRFC6979())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reqBody.SetSignature(sig.ToV2())
|
||||||
|
|
||||||
// form meta header
|
// form meta header
|
||||||
var meta v2session.RequestMetaHeader
|
var meta v2session.RequestMetaHeader
|
||||||
|
|
||||||
|
@ -592,13 +589,13 @@ func (c *Client) ContainerSetEACL(ctx context.Context, prm PrmContainerSetEACL)
|
||||||
// sign the eACL table
|
// sign the eACL table
|
||||||
signWrapper := v2signature.StableMarshalerWrapper{SM: reqBody.GetEACL()}
|
signWrapper := v2signature.StableMarshalerWrapper{SM: reqBody.GetEACL()}
|
||||||
|
|
||||||
err := sigutil.SignDataWithHandler(c.opts.key, signWrapper, func(sig *signature.Signature) {
|
sig, err := sigutil.SignData(c.opts.key, signWrapper, sigutil.SignWithRFC6979())
|
||||||
reqBody.SetSignature(sig.ToV2())
|
|
||||||
}, sigutil.SignWithRFC6979())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reqBody.SetSignature(sig.ToV2())
|
||||||
|
|
||||||
// form meta header
|
// form meta header
|
||||||
var meta v2session.RequestMetaHeader
|
var meta v2session.RequestMetaHeader
|
||||||
meta.SetSessionToken(prm.table.SessionToken().ToV2())
|
meta.SetSessionToken(prm.table.SessionToken().ToV2())
|
||||||
|
|
|
@ -87,21 +87,11 @@ func VerifyID(obj *Object) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func CalculateIDSignature(key *ecdsa.PrivateKey, id *oid.ID) (*signature.Signature, error) {
|
func CalculateIDSignature(key *ecdsa.PrivateKey, id *oid.ID) (*signature.Signature, error) {
|
||||||
sig := signature.New()
|
return sigutil.SignData(
|
||||||
|
|
||||||
if err := sigutil.SignDataWithHandler(
|
|
||||||
key,
|
key,
|
||||||
signatureV2.StableMarshalerWrapper{
|
signatureV2.StableMarshalerWrapper{
|
||||||
SM: id.ToV2(),
|
SM: id.ToV2(),
|
||||||
},
|
})
|
||||||
func(s *signature.Signature) {
|
|
||||||
*sig = *s
|
|
||||||
},
|
|
||||||
); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return sig, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func CalculateAndSetSignature(key *ecdsa.PrivateKey, obj *RawObject) error {
|
func CalculateAndSetSignature(key *ecdsa.PrivateKey, obj *RawObject) error {
|
||||||
|
@ -116,11 +106,11 @@ func CalculateAndSetSignature(key *ecdsa.PrivateKey, obj *RawObject) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func VerifyIDSignature(obj *Object) error {
|
func VerifyIDSignature(obj *Object) error {
|
||||||
return sigutil.VerifyDataWithSource(
|
return sigutil.VerifyData(
|
||||||
signatureV2.StableMarshalerWrapper{
|
signatureV2.StableMarshalerWrapper{
|
||||||
SM: obj.ID().ToV2(),
|
SM: obj.ID().ToV2(),
|
||||||
},
|
},
|
||||||
obj.Signature,
|
obj.Signature(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -260,13 +260,14 @@ func (x *GlobalTrust) Trust() *Trust {
|
||||||
func (x *GlobalTrust) Sign(key *ecdsa.PrivateKey) error {
|
func (x *GlobalTrust) Sign(key *ecdsa.PrivateKey) error {
|
||||||
v2 := (*reputation.GlobalTrust)(x)
|
v2 := (*reputation.GlobalTrust)(x)
|
||||||
|
|
||||||
return sigutil.SignDataWithHandler(
|
sig, err := sigutil.SignData(key,
|
||||||
key,
|
signatureV2.StableMarshalerWrapper{SM: v2.GetBody()})
|
||||||
signatureV2.StableMarshalerWrapper{SM: v2.GetBody()},
|
if err != nil {
|
||||||
func(sig *signature.Signature) {
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
v2.SetSignature(sig.ToV2())
|
v2.SetSignature(sig.ToV2())
|
||||||
},
|
return nil
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifySignature verifies global trust signature.
|
// VerifySignature verifies global trust signature.
|
||||||
|
@ -278,11 +279,9 @@ func (x *GlobalTrust) VerifySignature() error {
|
||||||
sigV2 = new(refs.Signature)
|
sigV2 = new(refs.Signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
return sigutil.VerifyDataWithSource(
|
return sigutil.VerifyData(
|
||||||
signatureV2.StableMarshalerWrapper{SM: v2.GetBody()},
|
signatureV2.StableMarshalerWrapper{SM: v2.GetBody()},
|
||||||
func() *signature.Signature {
|
signature.NewFromV2(sigV2),
|
||||||
return signature.NewFromV2(sigV2)
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -168,9 +168,13 @@ func (t *Token) Sign(key *ecdsa.PrivateKey) error {
|
||||||
SM: tV2.GetBody(),
|
SM: tV2.GetBody(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return sigutil.SignDataWithHandler(key, signedData, func(sig *signature.Signature) {
|
sig, err := sigutil.SignData(key, signedData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
tV2.SetSignature(sig.ToV2())
|
tV2.SetSignature(sig.ToV2())
|
||||||
})
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifySignature checks if token signature is
|
// VerifySignature checks if token signature is
|
||||||
|
@ -182,7 +186,7 @@ func (t *Token) VerifySignature() bool {
|
||||||
SM: tV2.GetBody(),
|
SM: tV2.GetBody(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return sigutil.VerifyDataWithSource(signedData, t.Signature) == nil
|
return sigutil.VerifyData(signedData, t.Signature()) == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signature returns Token signature.
|
// Signature returns Token signature.
|
||||||
|
|
|
@ -102,9 +102,13 @@ func (b *BearerToken) SignToken(key *ecdsa.PrivateKey) error {
|
||||||
|
|
||||||
signWrapper := v2signature.StableMarshalerWrapper{SM: b.token.GetBody()}
|
signWrapper := v2signature.StableMarshalerWrapper{SM: b.token.GetBody()}
|
||||||
|
|
||||||
return sigutil.SignDataWithHandler(key, signWrapper, func(sig *signature.Signature) {
|
sig, err := sigutil.SignData(key, signWrapper)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
b.token.SetSignature(sig.ToV2())
|
b.token.SetSignature(sig.ToV2())
|
||||||
})
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BearerToken) Signature() *signature.Signature {
|
func (b BearerToken) Signature() *signature.Signature {
|
||||||
|
@ -116,12 +120,10 @@ func (b BearerToken) VerifySignature() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return sigutil.VerifyDataWithSource(
|
|
||||||
v2signature.StableMarshalerWrapper{SM: b.token.GetBody()},
|
|
||||||
func() *signature.Signature {
|
|
||||||
sigV2 := b.token.GetSignature()
|
sigV2 := b.token.GetSignature()
|
||||||
return signature.NewFromV2(sigV2)
|
return sigutil.VerifyData(
|
||||||
})
|
v2signature.StableMarshalerWrapper{SM: b.token.GetBody()},
|
||||||
|
signature.NewFromV2(sigV2))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issuer returns owner.ID associated with the key that signed bearer token.
|
// Issuer returns owner.ID associated with the key that signed bearer token.
|
||||||
|
|
|
@ -2,9 +2,7 @@ package signature
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/elliptic"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/signature"
|
"github.com/nspcc-dev/neofs-sdk-go/signature"
|
||||||
|
@ -23,10 +21,6 @@ type DataWithSignature interface {
|
||||||
|
|
||||||
type SignOption func(*cfg)
|
type SignOption func(*cfg)
|
||||||
|
|
||||||
type KeySignatureHandler func(*signature.Signature)
|
|
||||||
|
|
||||||
type KeySignatureSource func() *signature.Signature
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// PrivateKeyCompressedSize is constant with compressed size of private key (SK).
|
// PrivateKeyCompressedSize is constant with compressed size of private key (SK).
|
||||||
// D coordinate stored, recover PK by formula x, y = curve.ScalarBaseMul(d,bytes).
|
// D coordinate stored, recover PK by formula x, y = curve.ScalarBaseMul(d,bytes).
|
||||||
|
@ -50,14 +44,14 @@ var (
|
||||||
ErrInvalidSignature = errors.New("invalid signature")
|
ErrInvalidSignature = errors.New("invalid signature")
|
||||||
)
|
)
|
||||||
|
|
||||||
func SignDataWithHandler(key *ecdsa.PrivateKey, src DataSource, handler KeySignatureHandler, opts ...SignOption) error {
|
func SignData(key *ecdsa.PrivateKey, src DataSource, opts ...SignOption) (*signature.Signature, error) {
|
||||||
if key == nil {
|
if key == nil {
|
||||||
return ErrEmptyPrivateKey
|
return nil, ErrEmptyPrivateKey
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := dataForSignature(src)
|
data, err := dataForSignature(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer bytesPool.Put(&data)
|
defer bytesPool.Put(&data)
|
||||||
|
|
||||||
|
@ -65,20 +59,17 @@ func SignDataWithHandler(key *ecdsa.PrivateKey, src DataSource, handler KeySigna
|
||||||
|
|
||||||
sigData, err := sign(cfg.defaultScheme, key, data)
|
sigData, err := sign(cfg.defaultScheme, key, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sig := signature.New()
|
sig := signature.New()
|
||||||
sig.SetKey((*keys.PublicKey)(&key.PublicKey).Bytes())
|
sig.SetKey((*keys.PublicKey)(&key.PublicKey).Bytes())
|
||||||
sig.SetSign(sigData)
|
sig.SetSign(sigData)
|
||||||
sig.SetScheme(cfg.defaultScheme)
|
sig.SetScheme(cfg.defaultScheme)
|
||||||
|
return sig, nil
|
||||||
handler(sig)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func VerifyDataWithSource(dataSrc DataSource, sigSrc KeySignatureSource, opts ...SignOption) error {
|
func VerifyData(dataSrc DataSource, sig *signature.Signature, opts ...SignOption) error {
|
||||||
data, err := dataForSignature(dataSrc)
|
data, err := dataForSignature(dataSrc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -87,36 +78,5 @@ func VerifyDataWithSource(dataSrc DataSource, sigSrc KeySignatureSource, opts ..
|
||||||
|
|
||||||
cfg := getConfig(opts...)
|
cfg := getConfig(opts...)
|
||||||
|
|
||||||
sig := sigSrc()
|
return verify(cfg, data, sig)
|
||||||
|
|
||||||
var pub *keys.PublicKey
|
|
||||||
if len(sig.Key()) != 0 {
|
|
||||||
pub, err = keys.NewPublicKeyFromBytes(sig.Key(), elliptic.P256())
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("%w: %v", ErrInvalidPublicKey, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scheme := sig.Scheme()
|
|
||||||
if scheme == signature.Unspecified {
|
|
||||||
scheme = cfg.defaultScheme
|
|
||||||
}
|
|
||||||
if cfg.restrictScheme != signature.Unspecified && scheme != cfg.restrictScheme {
|
|
||||||
return fmt.Errorf("%w: unexpected signature scheme", ErrInvalidSignature)
|
|
||||||
}
|
|
||||||
|
|
||||||
return verify(
|
|
||||||
scheme,
|
|
||||||
(*ecdsa.PublicKey)(pub),
|
|
||||||
data,
|
|
||||||
sig.Sign(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SignData(key *ecdsa.PrivateKey, v DataWithSignature, opts ...SignOption) error {
|
|
||||||
return SignDataWithHandler(key, v, v.SetSignature, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func VerifyData(src DataWithSignature, opts ...SignOption) error {
|
|
||||||
return VerifyDataWithSource(src, src.GetSignature, opts...)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/sha512"
|
"crypto/sha512"
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
@ -49,19 +50,31 @@ func sign(scheme signature.Scheme, key *ecdsa.PrivateKey, msg []byte) ([]byte, e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func verify(scheme signature.Scheme, key *ecdsa.PublicKey, msg []byte, sig []byte) error {
|
func verify(cfg *cfg, msg []byte, sig *signature.Signature) error {
|
||||||
|
pub, err := keys.NewPublicKeyFromBytes(sig.Key(), elliptic.P256())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%w: %v", ErrInvalidPublicKey, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
scheme := sig.Scheme()
|
||||||
|
if scheme == signature.Unspecified {
|
||||||
|
scheme = cfg.defaultScheme
|
||||||
|
}
|
||||||
|
if cfg.restrictScheme != signature.Unspecified && scheme != cfg.restrictScheme {
|
||||||
|
return fmt.Errorf("%w: unexpected signature scheme", ErrInvalidSignature)
|
||||||
|
}
|
||||||
|
|
||||||
switch scheme {
|
switch scheme {
|
||||||
case signature.ECDSAWithSHA512:
|
case signature.ECDSAWithSHA512:
|
||||||
h := sha512.Sum512(msg)
|
h := sha512.Sum512(msg)
|
||||||
r, s := unmarshalXY(sig)
|
r, s := unmarshalXY(sig.Sign())
|
||||||
if r != nil && s != nil && ecdsa.Verify(key, h[:], r, s) {
|
if r != nil && s != nil && ecdsa.Verify((*ecdsa.PublicKey)(pub), h[:], r, s) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return ErrInvalidSignature
|
return ErrInvalidSignature
|
||||||
case signature.RFC6979WithSHA256:
|
case signature.RFC6979WithSHA256:
|
||||||
p := (*keys.PublicKey)(key)
|
|
||||||
h := sha256.Sum256(msg)
|
h := sha256.Sum256(msg)
|
||||||
if p.Verify(sig, h[:]) {
|
if pub.Verify(sig.Sign(), h[:]) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return ErrInvalidSignature
|
return ErrInvalidSignature
|
||||||
|
|
Loading…
Reference in a new issue