1 package keyfunc_test
2
3 import (
4 "crypto/ecdsa"
5 "crypto/ed25519"
6 "crypto/elliptic"
7 "crypto/rand"
8 "crypto/rsa"
9 "crypto/sha256"
10 "fmt"
11 "testing"
12
13 "github.com/golang-jwt/jwt/v4"
14
15 "github.com/MicahParks/keyfunc"
16 "github.com/MicahParks/keyfunc/examples/custom/method"
17 )
18
19 const (
20
21 algAttribute = "alg"
22
23
24 kidAttribute = "kid"
25
26
27 testKID = "testkid"
28 )
29
30
31 func TestNewGivenCustom(t *testing.T) {
32 jwt.RegisterSigningMethod(method.CustomAlg, func() jwt.SigningMethod {
33 return method.EmptyCustom{}
34 })
35
36 givenKeys := make(map[string]keyfunc.GivenKey)
37 key := addCustom(givenKeys, testKID)
38
39 jwks := keyfunc.NewGiven(givenKeys)
40
41 token := jwt.New(method.EmptyCustom{})
42 token.Header[algAttribute] = method.CustomAlg
43 token.Header[kidAttribute] = testKID
44
45 signParseValidate(t, token, key, jwks)
46 }
47
48
49 func TestNewGivenKeyECDSA(t *testing.T) {
50 givenKeys := make(map[string]keyfunc.GivenKey)
51 key, err := addECDSA(givenKeys, testKID)
52 if err != nil {
53 t.Fatalf(err.Error())
54 }
55
56 jwks := keyfunc.NewGiven(givenKeys)
57
58 token := jwt.New(jwt.SigningMethodES256)
59 token.Header[kidAttribute] = testKID
60
61 signParseValidate(t, token, key, jwks)
62 }
63
64
65 func TestNewGivenKeyEdDSA(t *testing.T) {
66 givenKeys := make(map[string]keyfunc.GivenKey)
67 key, err := addEdDSA(givenKeys, testKID)
68 if err != nil {
69 t.Fatalf(err.Error())
70 }
71
72 jwks := keyfunc.NewGiven(givenKeys)
73
74 token := jwt.New(jwt.SigningMethodEdDSA)
75 token.Header[kidAttribute] = testKID
76
77 signParseValidate(t, token, key, jwks)
78 }
79
80
81 func TestNewGivenKeyHMAC(t *testing.T) {
82 givenKeys := make(map[string]keyfunc.GivenKey)
83 key, err := addHMAC(givenKeys, testKID)
84 if err != nil {
85 t.Fatalf(err.Error())
86 }
87
88 jwks := keyfunc.NewGiven(givenKeys)
89
90 token := jwt.New(jwt.SigningMethodHS256)
91 token.Header[kidAttribute] = testKID
92
93 signParseValidate(t, token, key, jwks)
94 }
95
96
97 func TestNewGivenKeyRSA(t *testing.T) {
98 givenKeys := make(map[string]keyfunc.GivenKey)
99 key, err := addRSA(givenKeys, testKID)
100 if err != nil {
101 t.Fatalf(err.Error())
102 }
103
104 jwks := keyfunc.NewGiven(givenKeys)
105
106 token := jwt.New(jwt.SigningMethodRS256)
107 token.Header[kidAttribute] = testKID
108
109 signParseValidate(t, token, key, jwks)
110 }
111
112
113 func addCustom(givenKeys map[string]keyfunc.GivenKey, kid string) (key string) {
114 key = ""
115 givenKeys[kid] = keyfunc.NewGivenCustom(key)
116 return key
117 }
118
119
120 func addECDSA(givenKeys map[string]keyfunc.GivenKey, kid string) (key *ecdsa.PrivateKey, err error) {
121 key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
122 if err != nil {
123 return nil, fmt.Errorf("failed to create ECDSA key: %w", err)
124 }
125
126 givenKeys[kid] = keyfunc.NewGivenECDSA(&key.PublicKey)
127
128 return key, nil
129 }
130
131
132 func addEdDSA(givenKeys map[string]keyfunc.GivenKey, kid string) (key ed25519.PrivateKey, err error) {
133 pub, key, err := ed25519.GenerateKey(rand.Reader)
134 if err != nil {
135 return nil, fmt.Errorf("failed to create ECDSA key: %w", err)
136 }
137
138 givenKeys[kid] = keyfunc.NewGivenEdDSA(pub)
139
140 return key, nil
141 }
142
143
144 func addHMAC(givenKeys map[string]keyfunc.GivenKey, kid string) (secret []byte, err error) {
145 secret = make([]byte, sha256.BlockSize)
146 _, err = rand.Read(secret)
147 if err != nil {
148 return nil, fmt.Errorf("failed to create HMAC secret: %w", err)
149 }
150
151 givenKeys[kid] = keyfunc.NewGivenHMAC(secret)
152
153 return secret, nil
154 }
155
156
157 func addRSA(givenKeys map[string]keyfunc.GivenKey, kid string) (key *rsa.PrivateKey, err error) {
158 key, err = rsa.GenerateKey(rand.Reader, 2048)
159 if err != nil {
160 return nil, fmt.Errorf("failed to create RSA key: %w", err)
161 }
162
163 givenKeys[kid] = keyfunc.NewGivenRSA(&key.PublicKey)
164
165 return key, nil
166 }
167
168
169 func signParseValidate(t *testing.T, token *jwt.Token, key interface{}, jwks *keyfunc.JWKS) {
170 jwtB64, err := token.SignedString(key)
171 if err != nil {
172 t.Fatalf(logFmt, "Failed to sign the JWT.", err)
173 }
174
175 parsed, err := jwt.Parse(jwtB64, jwks.Keyfunc)
176 if err != nil {
177 t.Fatalf(logFmt, "Failed to parse the JWT.", err)
178 }
179
180 if !parsed.Valid {
181 t.Fatalf("The JWT was not valid.")
182 }
183 }
184
View as plain text