github.com/TrueCloudLab/frostfs-api-go/v2@v2.0.0-20230228134343-196241c4e79a/util/signature/options.go (about) 1 package signature 2 3 import ( 4 "crypto/ecdsa" 5 "encoding/base64" 6 "fmt" 7 8 "github.com/TrueCloudLab/frostfs-api-go/v2/refs" 9 "github.com/TrueCloudLab/frostfs-api-go/v2/util/signature/walletconnect" 10 crypto "github.com/TrueCloudLab/frostfs-crypto" 11 ) 12 13 type cfg struct { 14 schemeFixed bool 15 scheme refs.SignatureScheme 16 buffer []byte 17 } 18 19 func defaultCfg() *cfg { 20 return new(cfg) 21 } 22 23 func verify(cfg *cfg, data []byte, sig *refs.Signature) error { 24 if !cfg.schemeFixed { 25 cfg.scheme = sig.GetScheme() 26 } 27 28 pub := crypto.UnmarshalPublicKey(sig.GetKey()) 29 if pub == nil { 30 return crypto.ErrEmptyPublicKey 31 } 32 33 switch cfg.scheme { 34 case refs.ECDSA_SHA512: 35 return crypto.Verify(pub, data, sig.GetSign()) 36 case refs.ECDSA_RFC6979_SHA256: 37 return crypto.VerifyRFC6979(pub, data, sig.GetSign()) 38 case refs.ECDSA_RFC6979_SHA256_WALLET_CONNECT: 39 buf := make([]byte, base64.StdEncoding.EncodedLen(len(data))) 40 base64.StdEncoding.Encode(buf, data) 41 if !walletconnect.Verify(pub, buf, sig.GetSign()) { 42 return crypto.ErrInvalidSignature 43 } 44 return nil 45 default: 46 return fmt.Errorf("unsupported signature scheme %s", cfg.scheme) 47 } 48 } 49 50 func sign(cfg *cfg, key *ecdsa.PrivateKey, data []byte) ([]byte, error) { 51 switch cfg.scheme { 52 case refs.ECDSA_SHA512: 53 return crypto.Sign(key, data) 54 case refs.ECDSA_RFC6979_SHA256: 55 return crypto.SignRFC6979(key, data) 56 case refs.ECDSA_RFC6979_SHA256_WALLET_CONNECT: 57 buf := make([]byte, base64.StdEncoding.EncodedLen(len(data))) 58 base64.StdEncoding.Encode(buf, data) 59 return walletconnect.Sign(key, buf) 60 default: 61 panic(fmt.Sprintf("unsupported scheme %s", cfg.scheme)) 62 } 63 } 64 65 func SignWithRFC6979() SignOption { 66 return func(c *cfg) { 67 c.schemeFixed = true 68 c.scheme = refs.ECDSA_RFC6979_SHA256 69 } 70 } 71 72 // WithBuffer allows providing pre-allocated buffer for signature verification. 73 func WithBuffer(buf []byte) SignOption { 74 return func(c *cfg) { 75 c.buffer = buf 76 } 77 } 78 79 func SignWithWalletConnect() SignOption { 80 return func(c *cfg) { 81 c.scheme = refs.ECDSA_RFC6979_SHA256_WALLET_CONNECT 82 } 83 }