| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- package jws
- import (
- "crypto/hmac"
- "crypto/sha256"
- "crypto/sha512"
- "hash"
- "github.com/lestrrat-go/jwx/internal/keyconv"
- "github.com/lestrrat-go/jwx/jwa"
- "github.com/pkg/errors"
- )
- var hmacSignFuncs = map[jwa.SignatureAlgorithm]hmacSignFunc{}
- func init() {
- algs := map[jwa.SignatureAlgorithm]func() hash.Hash{
- jwa.HS256: sha256.New,
- jwa.HS384: sha512.New384,
- jwa.HS512: sha512.New,
- }
- for alg, h := range algs {
- hmacSignFuncs[alg] = makeHMACSignFunc(h)
- }
- }
- func newHMACSigner(alg jwa.SignatureAlgorithm) Signer {
- return &HMACSigner{
- alg: alg,
- sign: hmacSignFuncs[alg], // we know this will succeed
- }
- }
- func makeHMACSignFunc(hfunc func() hash.Hash) hmacSignFunc {
- return func(payload []byte, key []byte) ([]byte, error) {
- h := hmac.New(hfunc, key)
- if _, err := h.Write(payload); err != nil {
- return nil, errors.Wrap(err, "failed to write payload using hmac")
- }
- return h.Sum(nil), nil
- }
- }
- func (s HMACSigner) Algorithm() jwa.SignatureAlgorithm {
- return s.alg
- }
- func (s HMACSigner) Sign(payload []byte, key interface{}) ([]byte, error) {
- var hmackey []byte
- if err := keyconv.ByteSliceKey(&hmackey, key); err != nil {
- return nil, errors.Wrapf(err, `invalid key type %T. []byte is required`, key)
- }
- if len(hmackey) == 0 {
- return nil, errors.New(`missing key while signing payload`)
- }
- return s.sign(payload, hmackey)
- }
- func newHMACVerifier(alg jwa.SignatureAlgorithm) Verifier {
- s := newHMACSigner(alg)
- return &HMACVerifier{signer: s}
- }
- func (v HMACVerifier) Verify(payload, signature []byte, key interface{}) (err error) {
- expected, err := v.signer.Sign(payload, key)
- if err != nil {
- return errors.Wrap(err, `failed to generated signature`)
- }
- if !hmac.Equal(signature, expected) {
- return errors.New(`failed to match hmac signature`)
- }
- return nil
- }
|