1 package jwt
2 3 import (
4 "sync"
5 )
6 7 var signingMethods = map[string]func() SigningMethod{}
8 var signingMethodLock = new(sync.RWMutex)
9 10 // SigningMethod can be used add new methods for signing or verifying tokens. It
11 // takes a decoded signature as an input in the Verify function and produces a
12 // signature in Sign. The signature is then usually base64 encoded as part of a
13 // JWT.
14 type SigningMethod interface {
15 Verify(signingString string, sig []byte, key any) error // Returns nil if signature is valid
16 Sign(signingString string, key any) ([]byte, error) // Returns signature or error
17 Alg() string // returns the alg identifier for this method (example: 'HS256')
18 }
19 20 // RegisterSigningMethod registers the "alg" name and a factory function for signing method.
21 // This is typically done during init() in the method's implementation
22 func RegisterSigningMethod(alg string, f func() SigningMethod) {
23 signingMethodLock.Lock()
24 defer signingMethodLock.Unlock()
25 26 signingMethods[alg] = f
27 }
28 29 // GetSigningMethod retrieves a signing method from an "alg" string
30 func GetSigningMethod(alg string) (method SigningMethod) {
31 signingMethodLock.RLock()
32 defer signingMethodLock.RUnlock()
33 34 if methodF, ok := signingMethods[alg]; ok {
35 method = methodF()
36 }
37 return
38 }
39 40 // GetAlgorithms returns a list of registered "alg" names
41 func GetAlgorithms() (algs []string) {
42 signingMethodLock.RLock()
43 defer signingMethodLock.RUnlock()
44 45 for alg := range signingMethods {
46 algs = append(algs, alg)
47 }
48 return
49 }
50