github.com/lestrrat-go/jwx/v2@v2.0.21/jws/verifier.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 VerifierFactory interface { 11 Create() (Verifier, error) 12 } 13 type VerifierFactoryFn func() (Verifier, error) 14 15 func (fn VerifierFactoryFn) Create() (Verifier, error) { 16 return fn() 17 } 18 19 var muVerifierDB sync.RWMutex 20 var verifierDB map[jwa.SignatureAlgorithm]VerifierFactory 21 22 // RegisterVerifier is used to register a factory object that creates 23 // Verifier objects based on the given algorithm. 24 // 25 // For example, if you would like to provide a custom verifier for 26 // jwa.EdDSA, use this function to register a `VerifierFactory` 27 // (probably in your `init()`) 28 // 29 // Unlike the `UnregisterVerifier` function, this function automatically 30 // calls `jwa.RegisterSignatureAlgorithm` to register the algorithm 31 // in the known algorithms database. 32 func RegisterVerifier(alg jwa.SignatureAlgorithm, f VerifierFactory) { 33 jwa.RegisterSignatureAlgorithm(alg) 34 muVerifierDB.Lock() 35 verifierDB[alg] = f 36 muVerifierDB.Unlock() 37 } 38 39 // UnregisterVerifier removes the signer factory associated with 40 // the given algorithm. 41 // 42 // Note that when you call this function, the algorithm itself is 43 // not automatically unregistered from the known algorithms database. 44 // This is because the algorithm may still be required for signing or 45 // some other operation (however unlikely, it is still possible). 46 // Therefore, in order to completely remove the algorithm, you must 47 // call `jwa.UnregisterSignatureAlgorithm` yourself. 48 func UnregisterVerifier(alg jwa.SignatureAlgorithm) { 49 muVerifierDB.Lock() 50 delete(verifierDB, alg) 51 muVerifierDB.Unlock() 52 } 53 54 func init() { 55 verifierDB = make(map[jwa.SignatureAlgorithm]VerifierFactory) 56 57 for _, alg := range []jwa.SignatureAlgorithm{jwa.RS256, jwa.RS384, jwa.RS512, jwa.PS256, jwa.PS384, jwa.PS512} { 58 RegisterVerifier(alg, func(alg jwa.SignatureAlgorithm) VerifierFactory { 59 return VerifierFactoryFn(func() (Verifier, error) { 60 return newRSAVerifier(alg), nil 61 }) 62 }(alg)) 63 } 64 65 for _, alg := range []jwa.SignatureAlgorithm{jwa.ES256, jwa.ES384, jwa.ES512, jwa.ES256K} { 66 RegisterVerifier(alg, func(alg jwa.SignatureAlgorithm) VerifierFactory { 67 return VerifierFactoryFn(func() (Verifier, error) { 68 return newECDSAVerifier(alg), nil 69 }) 70 }(alg)) 71 } 72 73 for _, alg := range []jwa.SignatureAlgorithm{jwa.HS256, jwa.HS384, jwa.HS512} { 74 RegisterVerifier(alg, func(alg jwa.SignatureAlgorithm) VerifierFactory { 75 return VerifierFactoryFn(func() (Verifier, error) { 76 return newHMACVerifier(alg), nil 77 }) 78 }(alg)) 79 } 80 81 RegisterVerifier(jwa.EdDSA, VerifierFactoryFn(func() (Verifier, error) { 82 return newEdDSAVerifier(), nil 83 })) 84 } 85 86 // NewVerifier creates a verifier that signs payloads using the given signature algorithm. 87 func NewVerifier(alg jwa.SignatureAlgorithm) (Verifier, error) { 88 muVerifierDB.RLock() 89 f, ok := verifierDB[alg] 90 muVerifierDB.RUnlock() 91 92 if ok { 93 return f.Create() 94 } 95 return nil, fmt.Errorf(`unsupported signature algorithm "%s"`, alg) 96 }