frostfs-api-go/util/signature/data.go
Leonard Lyubich 6191903326 Implement new request signing mechanism
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2020-09-18 10:40:45 +03:00

85 lines
1.7 KiB
Go

package signature
import (
"crypto/ecdsa"
crypto "github.com/nspcc-dev/neofs-crypto"
)
type DataSource interface {
ReadSignedData([]byte) ([]byte, error)
SignedDataSize() int
}
type DataWithSignature interface {
DataSource
GetSignatureWithKey() (key, sig []byte)
SetSignatureWithKey(key, sig []byte)
}
type SignOption func(*cfg)
type KeySignatureHandler func(key []byte, sig []byte)
type KeySignatureSource func() (key, sig []byte)
func DataSignature(key *ecdsa.PrivateKey, src DataSource, opts ...SignOption) ([]byte, error) {
if key == nil {
return nil, crypto.ErrEmptyPrivateKey
}
data, err := dataForSignature(src)
if err != nil {
return nil, err
}
defer bytesPool.Put(data)
cfg := defaultCfg()
for i := range opts {
opts[i](cfg)
}
return cfg.signFunc(key, data)
}
func SignDataWithHandler(key *ecdsa.PrivateKey, src DataSource, handler KeySignatureHandler, opts ...SignOption) error {
sig, err := DataSignature(key, src, opts...)
if err != nil {
return err
}
handler(crypto.MarshalPublicKey(&key.PublicKey), sig)
return nil
}
func VerifyDataWithSource(dataSrc DataSource, sigSrc KeySignatureSource, opts ...SignOption) error {
data, err := dataForSignature(dataSrc)
if err != nil {
return err
}
defer bytesPool.Put(data)
cfg := defaultCfg()
for i := range opts {
opts[i](cfg)
}
key, sig := sigSrc()
return cfg.verifyFunc(
crypto.UnmarshalPublicKey(key),
data,
sig,
)
}
func SignData(key *ecdsa.PrivateKey, v DataWithSignature, opts ...SignOption) error {
return SignDataWithHandler(key, v, v.SetSignatureWithKey, opts...)
}
func VerifyData(src DataWithSignature, opts ...SignOption) error {
return VerifyDataWithSource(src, src.GetSignatureWithKey, opts...)
}