github.com/lestrrat-go/jwx/v2@v2.0.21/jws/signer.go (about) 1 package jws 2 3 import ( 4 "fmt" 5 "sync" 6 7 "github.com/lestrrat-go/jwx/v2/jwa" 8 ) 9 10 type SignerFactory interface { 11 Create() (Signer, error) 12 } 13 type SignerFactoryFn func() (Signer, error) 14 15 func (fn SignerFactoryFn) Create() (Signer, error) { 16 return fn() 17 } 18 19 var muSignerDB sync.RWMutex 20 var signerDB map[jwa.SignatureAlgorithm]SignerFactory 21 22 // RegisterSigner is used to register a factory object that creates 23 // Signer objects based on the given algorithm. Previous object instantiated 24 // by the factory is discarded. 25 // 26 // For example, if you would like to provide a custom signer for 27 // jwa.EdDSA, use this function to register a `SignerFactory` 28 // (probably in your `init()`) 29 // 30 // Unlike the `UnregisterSigner` function, this function automatically 31 // calls `jwa.RegisterSignatureAlgorithm` to register the algorithm 32 // in the known algorithms database. 33 func RegisterSigner(alg jwa.SignatureAlgorithm, f SignerFactory) { 34 jwa.RegisterSignatureAlgorithm(alg) 35 muSignerDB.Lock() 36 signerDB[alg] = f 37 muSignerDB.Unlock() 38 39 // Remove previous signer, if there was one 40 removeSigner(alg) 41 } 42 43 // UnregisterSigner removes the signer factory associated with 44 // the given algorithm, as well as the signer instance created 45 // by the factory. 46 // 47 // Note that when you call this function, the algorithm itself is 48 // not automatically unregistered from the known algorithms database. 49 // This is because the algorithm may still be required for verification or 50 // some other operation (however unlikely, it is still possible). 51 // Therefore, in order to completely remove the algorithm, you must 52 // call `jwa.UnregisterSignatureAlgorithm` yourself. 53 func UnregisterSigner(alg jwa.SignatureAlgorithm) { 54 muSignerDB.Lock() 55 delete(signerDB, alg) 56 muSignerDB.Unlock() 57 // Remove previous signer 58 removeSigner(alg) 59 } 60 61 func init() { 62 signerDB = make(map[jwa.SignatureAlgorithm]SignerFactory) 63 64 for _, alg := range []jwa.SignatureAlgorithm{jwa.RS256, jwa.RS384, jwa.RS512, jwa.PS256, jwa.PS384, jwa.PS512} { 65 RegisterSigner(alg, func(alg jwa.SignatureAlgorithm) SignerFactory { 66 return SignerFactoryFn(func() (Signer, error) { 67 return newRSASigner(alg), nil 68 }) 69 }(alg)) 70 } 71 72 for _, alg := range []jwa.SignatureAlgorithm{jwa.ES256, jwa.ES384, jwa.ES512, jwa.ES256K} { 73 RegisterSigner(alg, func(alg jwa.SignatureAlgorithm) SignerFactory { 74 return SignerFactoryFn(func() (Signer, error) { 75 return newECDSASigner(alg), nil 76 }) 77 }(alg)) 78 } 79 80 for _, alg := range []jwa.SignatureAlgorithm{jwa.HS256, jwa.HS384, jwa.HS512} { 81 RegisterSigner(alg, func(alg jwa.SignatureAlgorithm) SignerFactory { 82 return SignerFactoryFn(func() (Signer, error) { 83 return newHMACSigner(alg), nil 84 }) 85 }(alg)) 86 } 87 88 RegisterSigner(jwa.EdDSA, SignerFactoryFn(func() (Signer, error) { 89 return newEdDSASigner(), nil 90 })) 91 } 92 93 // NewSigner creates a signer that signs payloads using the given signature algorithm. 94 func NewSigner(alg jwa.SignatureAlgorithm) (Signer, error) { 95 muSignerDB.RLock() 96 f, ok := signerDB[alg] 97 muSignerDB.RUnlock() 98 99 if ok { 100 return f.Create() 101 } 102 return nil, fmt.Errorf(`unsupported signature algorithm "%s"`, alg) 103 } 104 105 type noneSigner struct{} 106 107 func (noneSigner) Algorithm() jwa.SignatureAlgorithm { 108 return jwa.NoSignature 109 } 110 111 func (noneSigner) Sign([]byte, interface{}) ([]byte, error) { 112 return nil, nil 113 }