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  }