34
34
Public PublicKey
35
35
Private PrivateKey
36
36
MaxAge time.Duration // optional.
37
+ Encrypt InjectFunc // optional.
38
+ Decrypt InjectFunc // optional.
37
39
}
38
40
39
41
// Keys is a map which holds the key id and a key pair.
@@ -75,11 +77,20 @@ type (
75
77
Alg string `json:"alg" yaml:"Alg" toml:"Alg" ini:"alg"`
76
78
Private string `json:"private" yaml:"Private" toml:"Private" ini:"private"`
77
79
Public string `json:"public" yaml:"Public" toml:"Public" ini:"public"`
78
- // Token expiration. Optional .
80
+ // MaxAge sets the token expiration. It is optional .
79
81
// If greater than zero then the MaxAge token validation
80
82
// will be appended to the "VerifyToken" and the token is invalid
81
83
// after expiration of its sign time.
82
84
MaxAge time.Duration `json:"max_age" yaml:"MaxAge" toml:"MaxAge" ini:"max_age"`
85
+
86
+ // EncryptionKey enables encryption on the generated token. It is optional.
87
+ // Encryption using the Galois Counter mode of operation with
88
+ // AES cipher symmetric-key cryptographic.
89
+ //
90
+ // The value should be the AES key,
91
+ // either 16, 24, or 32 bytes to select
92
+ // AES-128, AES-192, or AES-256.
93
+ EncryptionKey string `json:"encryption_key" yaml:"EncryptionKey" toml:"EncryptionKey" ini:"encryption_key"`
83
94
}
84
95
)
85
96
@@ -131,6 +142,16 @@ func (c KeysConfiguration) Load() (Keys, error) {
131
142
p .Public = entry .Public
132
143
}
133
144
145
+ if entry .EncryptionKey != "" {
146
+ encrypt , decrypt , err := GCM ([]byte (entry .EncryptionKey ), nil )
147
+ if err != nil {
148
+ return nil , fmt .Errorf ("jwt: load keys: build encryption: %w" , err )
149
+ }
150
+
151
+ p .Encrypt = encrypt
152
+ p .Decrypt = decrypt
153
+ }
154
+
134
155
parsedKeys [entry .ID ] = p
135
156
}
136
157
@@ -155,33 +176,33 @@ func (keys Keys) Register(alg Alg, kid string, pubKey PublicKey, privKey Private
155
176
156
177
// ValidateHeader validates the given json header value (base64 decoded) based on the "keys".
157
178
// Keys structure completes the `HeaderValidator` interface.
158
- func (keys Keys ) ValidateHeader (alg string , headerDecoded []byte ) (Alg , PublicKey , error ) {
179
+ func (keys Keys ) ValidateHeader (alg string , headerDecoded []byte ) (Alg , PublicKey , InjectFunc , error ) {
159
180
var h HeaderWithKid
160
181
161
182
err := Unmarshal (headerDecoded , & h )
162
183
if err != nil {
163
- return nil , nil , err
184
+ return nil , nil , nil , err
164
185
}
165
186
166
187
if h .Kid == "" {
167
- return nil , nil , ErrEmptyKid
188
+ return nil , nil , nil , ErrEmptyKid
168
189
}
169
190
170
191
key , ok := keys .Get (h .Kid )
171
192
if ! ok {
172
- return nil , nil , ErrUnknownKid
193
+ return nil , nil , nil , ErrUnknownKid
173
194
}
174
195
175
196
if h .Alg != key .Alg .Name () {
176
- return nil , nil , ErrTokenAlg
197
+ return nil , nil , nil , ErrTokenAlg
177
198
}
178
199
179
200
// If for some reason a specific alg was given by the caller then check that as well.
180
201
if alg != "" && alg != h .Alg {
181
- return nil , nil , ErrTokenAlg
202
+ return nil , nil , nil , ErrTokenAlg
182
203
}
183
204
184
- return key .Alg , key .Public , nil
205
+ return key .Alg , key .Public , key . Decrypt , nil
185
206
}
186
207
187
208
// SignToken signs the "claims" using the given "alg" based a specific key.
@@ -195,7 +216,7 @@ func (keys Keys) SignToken(kid string, claims interface{}, opts ...SignOption) (
195
216
opts = append ([]SignOption {MaxAge (k .MaxAge )}, opts ... )
196
217
}
197
218
198
- return SignWithHeader (k .Alg , k .Private , claims , HeaderWithKid {
219
+ return SignEncryptedWithHeader (k .Alg , k .Private , k . Encrypt , claims , HeaderWithKid {
199
220
Kid : kid ,
200
221
Alg : k .Alg .Name (),
201
222
}, opts ... )
0 commit comments