forked from lestrrat-go/jwx
/
hmac.go
63 lines (50 loc) · 1.28 KB
/
hmac.go
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
package sign
import (
"crypto/hmac"
"crypto/sha256"
"crypto/sha512"
"hash"
"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 newHMAC(alg jwa.SignatureAlgorithm) (*HMACSigner, error) {
signer, ok := HMACSignFuncs[alg]
if !ok {
return nil, errors.Errorf(`unsupported algorithm while trying to create HMAC signer: %s`, alg)
}
return &HMACSigner{
alg: alg,
sign: signer,
}, nil
}
func makeHMACSignFunc(hfunc func() hash.Hash) hmacSignFunc {
return hmacSignFunc(func(payload []byte, key []byte) ([]byte, error) {
h := hmac.New(hfunc, key)
h.Write(payload)
return h.Sum(nil), nil
})
}
func (s HMACSigner) Algorithm() jwa.SignatureAlgorithm {
return s.alg
}
func (s HMACSigner) Sign(payload []byte, key interface{}) ([]byte, error) {
hmackey, ok := key.([]byte)
if !ok {
return nil, errors.Errorf(`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)
}