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