github.com/TrueCloudLab/frostfs-api-go/v2@v2.0.0-20230228134343-196241c4e79a/util/signature/data.go (about) 1 package signature 2 3 import ( 4 "crypto/ecdsa" 5 6 "github.com/TrueCloudLab/frostfs-api-go/v2/refs" 7 crypto "github.com/TrueCloudLab/frostfs-crypto" 8 ) 9 10 type DataSource interface { 11 ReadSignedData([]byte) ([]byte, error) 12 SignedDataSize() int 13 } 14 15 type DataWithSignature interface { 16 DataSource 17 GetSignature() *refs.Signature 18 SetSignature(*refs.Signature) 19 } 20 21 type SignOption func(*cfg) 22 23 type KeySignatureHandler func(*refs.Signature) 24 25 type KeySignatureSource func() *refs.Signature 26 27 func SignDataWithHandler(key *ecdsa.PrivateKey, src DataSource, handler KeySignatureHandler, opts ...SignOption) error { 28 if key == nil { 29 return crypto.ErrEmptyPrivateKey 30 } 31 32 cfg := defaultCfg() 33 34 for i := range opts { 35 opts[i](cfg) 36 } 37 38 data, err := readSignedData(cfg, src) 39 if err != nil { 40 return err 41 } 42 43 sigData, err := sign(cfg, key, data) 44 if err != nil { 45 return err 46 } 47 48 sig := new(refs.Signature) 49 sig.SetScheme(cfg.scheme) 50 sig.SetKey(crypto.MarshalPublicKey(&key.PublicKey)) 51 sig.SetSign(sigData) 52 handler(sig) 53 54 return nil 55 } 56 57 func VerifyDataWithSource(dataSrc DataSource, sigSrc KeySignatureSource, opts ...SignOption) error { 58 cfg := defaultCfg() 59 60 for i := range opts { 61 opts[i](cfg) 62 } 63 64 data, err := readSignedData(cfg, dataSrc) 65 if err != nil { 66 return err 67 } 68 69 return verify(cfg, data, sigSrc()) 70 } 71 72 func SignData(key *ecdsa.PrivateKey, v DataWithSignature, opts ...SignOption) error { 73 return SignDataWithHandler(key, v, v.SetSignature, opts...) 74 } 75 76 func VerifyData(src DataWithSignature, opts ...SignOption) error { 77 return VerifyDataWithSource(src, src.GetSignature, opts...) 78 } 79 80 func readSignedData(cfg *cfg, src DataSource) ([]byte, error) { 81 size := src.SignedDataSize() 82 if cfg.buffer == nil || cap(cfg.buffer) < size { 83 cfg.buffer = make([]byte, size) 84 } else { 85 cfg.buffer = cfg.buffer[:size] 86 } 87 return src.ReadSignedData(cfg.buffer) 88 }