[#157] util/signature: Revive removed features

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2022-03-02 14:41:37 +03:00 committed by Alex Vanin
parent a292150d42
commit d109594d75
2 changed files with 55 additions and 16 deletions

View file

@ -44,14 +44,42 @@ var (
ErrInvalidSignature = errors.New("invalid signature") ErrInvalidSignature = errors.New("invalid signature")
) )
func SignData(key *ecdsa.PrivateKey, src DataSource, opts ...SignOption) (*signature.Signature, error) { func SignData(key *ecdsa.PrivateKey, src DataSource, opts ...SignOption) (res *signature.Signature, err error) {
err = signDataWithHandler(key, src, func(key, sig []byte, scheme signature.Scheme) {
res = new(signature.Signature)
res.SetKey(key)
res.SetSign(sig)
res.SetScheme(scheme)
}, opts...)
return
}
func VerifyData(dataSrc DataSource, sig *signature.Signature, opts ...SignOption) error {
return verifyDataWithSource(dataSrc, func() ([]byte, []byte, signature.Scheme) {
return sig.Key(), sig.Sign(), sig.Scheme()
}, opts...)
}
func SignDataWithHandler(key *ecdsa.PrivateKey, src DataSource, handler func(key, sig []byte)) error {
return signDataWithHandler(key, src, func(key, sig []byte, scheme signature.Scheme) {
handler(key, sig)
})
}
func signDataWithHandler(
key *ecdsa.PrivateKey,
src DataSource,
handler func(key, sig []byte, scheme signature.Scheme),
opts ...SignOption,
) error {
if key == nil { if key == nil {
return nil, ErrEmptyPrivateKey return ErrEmptyPrivateKey
} }
data, err := dataForSignature(src) data, err := dataForSignature(src)
if err != nil { if err != nil {
return nil, err return err
} }
defer bytesPool.Put(&data) defer bytesPool.Put(&data)
@ -59,17 +87,26 @@ func SignData(key *ecdsa.PrivateKey, src DataSource, opts ...SignOption) (*signa
sigData, err := sign(cfg.scheme, key, data) sigData, err := sign(cfg.scheme, key, data)
if err != nil { if err != nil {
return nil, err return err
} }
sig := signature.New() handler((*keys.PublicKey)(&key.PublicKey).Bytes(), sigData, cfg.scheme)
sig.SetKey((*keys.PublicKey)(&key.PublicKey).Bytes())
sig.SetSign(sigData) return nil
sig.SetScheme(cfg.scheme)
return sig, nil
} }
func VerifyData(dataSrc DataSource, sig *signature.Signature, opts ...SignOption) error { func VerifyDataWithSource(dataSrc DataSource, sigSrc func() (key, sig []byte)) error {
return verifyDataWithSource(dataSrc, func() ([]byte, []byte, signature.Scheme) {
key, sign := sigSrc()
return key, sign, signature.ECDSAWithSHA512
})
}
func verifyDataWithSource(
dataSrc DataSource,
sigSrc func() (key, sig []byte, scheme signature.Scheme),
opts ...SignOption,
) error {
data, err := dataForSignature(dataSrc) data, err := dataForSignature(dataSrc)
if err != nil { if err != nil {
return err return err
@ -78,5 +115,5 @@ func VerifyData(dataSrc DataSource, sig *signature.Signature, opts ...SignOption
cfg := getConfig(opts...) cfg := getConfig(opts...)
return verify(cfg, data, sig) return verify(cfg, data, sigSrc)
} }

View file

@ -49,27 +49,29 @@ func sign(scheme signature.Scheme, key *ecdsa.PrivateKey, msg []byte) ([]byte, e
} }
} }
func verify(cfg *cfg, msg []byte, sig *signature.Signature) error { func verify(cfg *cfg, msg []byte, f func() (key, sign []byte, scheme signature.Scheme)) error {
pub, err := keys.NewPublicKeyFromBytes(sig.Key(), elliptic.P256()) key, sign, scheme := f()
pub, err := keys.NewPublicKeyFromBytes(key, elliptic.P256())
if err != nil { if err != nil {
return fmt.Errorf("%w: %v", ErrInvalidPublicKey, err) return fmt.Errorf("%w: %v", ErrInvalidPublicKey, err)
} }
if !cfg.schemeFixed { if !cfg.schemeFixed {
cfg.scheme = sig.Scheme() cfg.scheme = scheme
} }
switch cfg.scheme { switch cfg.scheme {
case signature.ECDSAWithSHA512: case signature.ECDSAWithSHA512:
h := sha512.Sum512(msg) h := sha512.Sum512(msg)
r, s := unmarshalXY(sig.Sign()) r, s := unmarshalXY(sign)
if r != nil && s != nil && ecdsa.Verify((*ecdsa.PublicKey)(pub), 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:
h := sha256.Sum256(msg) h := sha256.Sum256(msg)
if pub.Verify(sig.Sign(), h[:]) { if pub.Verify(sign, h[:]) {
return nil return nil
} }
return ErrInvalidSignature return ErrInvalidSignature