[#150] util/signature: Simplify public interface

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2022-02-24 14:45:52 +03:00 committed by LeL
parent 1c7dd03cf5
commit d716765c1a
7 changed files with 68 additions and 103 deletions

View file

@ -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())

View file

@ -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(),
)
}

View file

@ -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) {
v2.SetSignature(sig.ToV2())
},
)
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),
)
}

View file

@ -168,9 +168,13 @@ func (t *Token) Sign(key *ecdsa.PrivateKey) error {
SM: tV2.GetBody(),
}
return sigutil.SignDataWithHandler(key, signedData, func(sig *signature.Signature) {
tV2.SetSignature(sig.ToV2())
})
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.

View file

@ -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) {
b.token.SetSignature(sig.ToV2())
})
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(
sigV2 := b.token.GetSignature()
return sigutil.VerifyData(
v2signature.StableMarshalerWrapper{SM: b.token.GetBody()},
func() *signature.Signature {
sigV2 := b.token.GetSignature()
return signature.NewFromV2(sigV2)
})
signature.NewFromV2(sigV2))
}
// Issuer returns owner.ID associated with the key that signed bearer token.

View file

@ -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)
}

View file

@ -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