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
|
||||
signWrapper := v2signature.StableMarshalerWrapper{SM: reqBody.GetContainer()}
|
||||
|
||||
err := sigutil.SignDataWithHandler(c.opts.key, signWrapper, func(sig *signature.Signature) {
|
||||
reqBody.SetSignature(sig.ToV2())
|
||||
}, sigutil.SignWithRFC6979())
|
||||
sig, err := sigutil.SignData(c.opts.key, signWrapper, sigutil.SignWithRFC6979())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reqBody.SetSignature(sig.ToV2())
|
||||
|
||||
// form meta header
|
||||
var meta v2session.RequestMetaHeader
|
||||
meta.SetSessionToken(prm.cnr.SessionToken().ToV2())
|
||||
|
@ -393,19 +393,16 @@ func (c *Client) ContainerDelete(ctx context.Context, prm PrmContainerDelete) (*
|
|||
reqBody := new(v2container.DeleteRequestBody)
|
||||
reqBody.SetContainerID(prm.id.ToV2())
|
||||
|
||||
signWrapper := delContainerSignWrapper{body: reqBody}
|
||||
|
||||
// sign container
|
||||
err := sigutil.SignDataWithHandler(c.opts.key,
|
||||
delContainerSignWrapper{
|
||||
body: reqBody,
|
||||
},
|
||||
func(sig *signature.Signature) {
|
||||
reqBody.SetSignature(sig.ToV2())
|
||||
},
|
||||
sigutil.SignWithRFC6979())
|
||||
sig, err := sigutil.SignData(c.opts.key, signWrapper, sigutil.SignWithRFC6979())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reqBody.SetSignature(sig.ToV2())
|
||||
|
||||
// form meta header
|
||||
var meta v2session.RequestMetaHeader
|
||||
|
||||
|
@ -592,13 +589,13 @@ func (c *Client) ContainerSetEACL(ctx context.Context, prm PrmContainerSetEACL)
|
|||
// sign the eACL table
|
||||
signWrapper := v2signature.StableMarshalerWrapper{SM: reqBody.GetEACL()}
|
||||
|
||||
err := sigutil.SignDataWithHandler(c.opts.key, signWrapper, func(sig *signature.Signature) {
|
||||
reqBody.SetSignature(sig.ToV2())
|
||||
}, sigutil.SignWithRFC6979())
|
||||
sig, err := sigutil.SignData(c.opts.key, signWrapper, sigutil.SignWithRFC6979())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reqBody.SetSignature(sig.ToV2())
|
||||
|
||||
// form meta header
|
||||
var meta v2session.RequestMetaHeader
|
||||
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) {
|
||||
sig := signature.New()
|
||||
|
||||
if err := sigutil.SignDataWithHandler(
|
||||
return sigutil.SignData(
|
||||
key,
|
||||
signatureV2.StableMarshalerWrapper{
|
||||
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 {
|
||||
|
@ -116,11 +106,11 @@ func CalculateAndSetSignature(key *ecdsa.PrivateKey, obj *RawObject) error {
|
|||
}
|
||||
|
||||
func VerifyIDSignature(obj *Object) error {
|
||||
return sigutil.VerifyDataWithSource(
|
||||
return sigutil.VerifyData(
|
||||
signatureV2.StableMarshalerWrapper{
|
||||
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 {
|
||||
v2 := (*reputation.GlobalTrust)(x)
|
||||
|
||||
return sigutil.SignDataWithHandler(
|
||||
key,
|
||||
signatureV2.StableMarshalerWrapper{SM: v2.GetBody()},
|
||||
func(sig *signature.Signature) {
|
||||
sig, err := sigutil.SignData(key,
|
||||
signatureV2.StableMarshalerWrapper{SM: v2.GetBody()})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
v2.SetSignature(sig.ToV2())
|
||||
},
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// VerifySignature verifies global trust signature.
|
||||
|
@ -278,11 +279,9 @@ func (x *GlobalTrust) VerifySignature() error {
|
|||
sigV2 = new(refs.Signature)
|
||||
}
|
||||
|
||||
return sigutil.VerifyDataWithSource(
|
||||
return sigutil.VerifyData(
|
||||
signatureV2.StableMarshalerWrapper{SM: v2.GetBody()},
|
||||
func() *signature.Signature {
|
||||
return signature.NewFromV2(sigV2)
|
||||
},
|
||||
signature.NewFromV2(sigV2),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -168,9 +168,13 @@ func (t *Token) Sign(key *ecdsa.PrivateKey) error {
|
|||
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())
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// VerifySignature checks if token signature is
|
||||
|
@ -182,7 +186,7 @@ func (t *Token) VerifySignature() bool {
|
|||
SM: tV2.GetBody(),
|
||||
}
|
||||
|
||||
return sigutil.VerifyDataWithSource(signedData, t.Signature) == nil
|
||||
return sigutil.VerifyData(signedData, t.Signature()) == nil
|
||||
}
|
||||
|
||||
// Signature returns Token signature.
|
||||
|
|
|
@ -102,9 +102,13 @@ func (b *BearerToken) SignToken(key *ecdsa.PrivateKey) error {
|
|||
|
||||
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())
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b BearerToken) Signature() *signature.Signature {
|
||||
|
@ -116,12 +120,10 @@ func (b BearerToken) VerifySignature() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
return sigutil.VerifyDataWithSource(
|
||||
v2signature.StableMarshalerWrapper{SM: b.token.GetBody()},
|
||||
func() *signature.Signature {
|
||||
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.
|
||||
|
|
|
@ -2,9 +2,7 @@ package signature
|
|||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/signature"
|
||||
|
@ -23,10 +21,6 @@ type DataWithSignature interface {
|
|||
|
||||
type SignOption func(*cfg)
|
||||
|
||||
type KeySignatureHandler func(*signature.Signature)
|
||||
|
||||
type KeySignatureSource func() *signature.Signature
|
||||
|
||||
const (
|
||||
// PrivateKeyCompressedSize is constant with compressed size of private key (SK).
|
||||
// D coordinate stored, recover PK by formula x, y = curve.ScalarBaseMul(d,bytes).
|
||||
|
@ -50,14 +44,14 @@ var (
|
|||
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 {
|
||||
return ErrEmptyPrivateKey
|
||||
return nil, ErrEmptyPrivateKey
|
||||
}
|
||||
|
||||
data, err := dataForSignature(src)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
defer bytesPool.Put(&data)
|
||||
|
||||
|
@ -65,20 +59,17 @@ func SignDataWithHandler(key *ecdsa.PrivateKey, src DataSource, handler KeySigna
|
|||
|
||||
sigData, err := sign(cfg.defaultScheme, key, data)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sig := signature.New()
|
||||
sig.SetKey((*keys.PublicKey)(&key.PublicKey).Bytes())
|
||||
sig.SetSign(sigData)
|
||||
sig.SetScheme(cfg.defaultScheme)
|
||||
|
||||
handler(sig)
|
||||
|
||||
return nil
|
||||
return sig, nil
|
||||
}
|
||||
|
||||
func VerifyDataWithSource(dataSrc DataSource, sigSrc KeySignatureSource, opts ...SignOption) error {
|
||||
func VerifyData(dataSrc DataSource, sig *signature.Signature, opts ...SignOption) error {
|
||||
data, err := dataForSignature(dataSrc)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -87,36 +78,5 @@ func VerifyDataWithSource(dataSrc DataSource, sigSrc KeySignatureSource, opts ..
|
|||
|
||||
cfg := getConfig(opts...)
|
||||
|
||||
sig := sigSrc()
|
||||
|
||||
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...)
|
||||
return verify(cfg, data, sig)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"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 {
|
||||
case signature.ECDSAWithSHA512:
|
||||
h := sha512.Sum512(msg)
|
||||
r, s := unmarshalXY(sig)
|
||||
if r != nil && s != nil && ecdsa.Verify(key, h[:], r, s) {
|
||||
r, s := unmarshalXY(sig.Sign())
|
||||
if r != nil && s != nil && ecdsa.Verify((*ecdsa.PublicKey)(pub), h[:], r, s) {
|
||||
return nil
|
||||
}
|
||||
return ErrInvalidSignature
|
||||
case signature.RFC6979WithSHA256:
|
||||
p := (*keys.PublicKey)(key)
|
||||
h := sha256.Sum256(msg)
|
||||
if p.Verify(sig, h[:]) {
|
||||
if pub.Verify(sig.Sign(), h[:]) {
|
||||
return nil
|
||||
}
|
||||
return ErrInvalidSignature
|
||||
|
|
Loading…
Reference in a new issue