diff --git a/client/container.go b/client/container.go index 4e2aa7d..6d0dfe8 100644 --- a/client/container.go +++ b/client/container.go @@ -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()) diff --git a/object/fmt.go b/object/fmt.go index 2600d84..38646ad 100644 --- a/object/fmt.go +++ b/object/fmt.go @@ -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(), ) } diff --git a/reputation/trust.go b/reputation/trust.go index 034b937..62f1d31 100644 --- a/reputation/trust.go +++ b/reputation/trust.go @@ -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), ) } diff --git a/session/session.go b/session/session.go index fe5a8ae..5d08e63 100644 --- a/session/session.go +++ b/session/session.go @@ -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. diff --git a/token/bearer.go b/token/bearer.go index b40159b..3cd3088 100644 --- a/token/bearer.go +++ b/token/bearer.go @@ -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. diff --git a/util/signature/data.go b/util/signature/data.go index 3ded29b..9351126 100644 --- a/util/signature/data.go +++ b/util/signature/data.go @@ -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) } diff --git a/util/signature/options.go b/util/signature/options.go index 9b6b0e7..1400148 100644 --- a/util/signature/options.go +++ b/util/signature/options.go @@ -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