1Changes
2=======
3
4v1.2.7 26 Sep 2021
5[New features]
6  * `jwt.InferAlgorithmFromKey()` option is now available to "guess"
7    the algorithm used to verify the JWS signature on a JWT using
8    a JWKS (key set). This allows you to match JWKs that do not have
9    the `alg` field populated.
10
11    We understand that some providers do not provide the `alg` field,
12    which is a nuisance to users. But from a purely security minded PoV,
13    we don't think that this "try until something works" approach is a
14    good one, even if there are no known exploits. This is why the
15    default `jwt.Parse` mechanism is unchanged, and an explicit option
16    has been added.
17
18  * Types `jwt.KeySetProvider` and `jwk.KeySetProviderFunc` have been
19    added. Along with `jwt.WithKeySetProvider()` option, `jwt.Parse`
20    can now choose the `jwk.Set` to use for signature verification
21    dynamically using the UNVERFIEID token as a clue.
22
23    You should NOT trust the token information too much. For example,
24    DO NOT directly use values from the token as verificatin parameters
25    (such as the signature algorithm)
26
27  * `jwt.WithValidator()` has been added to allow users pass in aribtrary
28    validation code to the `jwt.Validate()` method.
29
30    It is also now possible to pass in a `context.Context` object to
31    `jwt.Validate()` using `jwt.WithContext()` option.
32
33[Miscellaneous]
34  * Make the error messages when `jwt.ParseRequest` fails a bit better.
35  * Moved around documentation within the repository
36  * Validation logic for `jwt.Validate()` has been refactored to use the
37    new `jwt.Validator` mechanism
38
39v1.2.6 24 Aug 2021
40[New features]
41  * Support `crypto.Signer` keys for RSA, ECDSA, and EdDSA family
42    of signatures in `jws.Sign`
43[Miscellaneous]
44  * `jwx.GuessFormat()` now requires the presense of both `payload` and
45    `signatures` keys for it to guess that a JSON object is a JWS message.
46  * Slightly enhance `jwt.Parse()` performance.
47
48v1.2.5 04 Aug 2021
49[New features]
50  * Implement RFC7797. The value of the header field `b64` changes
51    how the payload is treated in JWS
52  * Implement detached payloads for JWS
53  * Implement (jwk.AutoRefresh).ErrorSink() to register a channel
54    where you can receive errors from fetches and parses that occur during
55    JWK(s) retrieval.
56
57v1.2.4 15 Jul 2021
58[Bug fixes]
59  * We had the same off-by-one in another place and jumped the gun on
60    releasing a new version. At least we were making mistakes uniformally :/
61    `(jwk.Set).Remove` should finally be fixed.
62
63[New features]
64  * `(jwk.Set).Clone()` has been added.
65
66v1.2.3 15 Jul 2021
67[Bug fixes]
68  * jwk.Set incorrectly removed 2 elements instead of one.
69
70[Miscellaneous]
71  * github.com/goccy/go-json has been upgraded to v0.7.4
72
73v1.2.2 13 Jul 2021
74[Deprecation notice]
75  * `(jwe.Message).Decrypt()` will be removed from the API upon the next
76    major release.
77
78[Bug Fixes]
79  * `jwe.Decrypt` and `(jwe.Message).Decrypt()` failed to decrypt even
80    with the correct message contents when used along with `jwe.RegisterCustomField`
81
82[New features]
83  JWX
84  * Add GuessFormat() function to guess what the payload is.
85
86  JWT
87  * Options `jwt.WithMinDelta()`, `jwt.WithMaxDelta()` have been added.
88    These can be used to compare time-based fields in the JWT object.
89  * Option `jwt.WithRequiredClaim()` has been added. This can be used
90    to check that JWT contains the given claim.
91  * `jwt.Parse` now understands payloads that have been encrypted _and_ signed.
92    This is more in line with the RFC than the previous implementation, but
93    due to the fact that it requires a couple of extra unmarshaling, it may
94    add some amount of overhead.
95  * `jwt.Serializer` has been added as an easy wrapper to perform multiple
96     levels of serializations (e.g. apply JWS, then JWE)
97
98  JWE
99  * Option `jwe.WithMessage()` has been added. This allows the user to
100    obtain both the decrypted payload _and_ the raw `*jwe.Message` in one
101    go when `jwe.Decrypt()` is called
102  * Option `jwe.WithPostParser()`, along with `jwe.PostParser` and `jwe.PostParseFunc`
103    has been added. This allows advanced users to hook into the `jwe.Decrypt()`
104    process. The hook is called right after the JWE message has been parsed,
105    but before the actual decryption has taken place.
106  * `(jwe.Message).Decrypt()` has been marked for deprecation in a next major release.
107
108  JWS
109  * Option `jwe.WithMessage()` has been added. This allows the user to
110    obtain both the verified payload _and_ the raw `*jws.Message` in one
111    go when `jws.Verify()` is called
112  * Options to `jws.Sign()` are not of type `jws.SignOption`. There should be
113    no user-visible effects unless you were storing these somewhere.
114
115v1.2.1 02 Jun 2021
116[New features]
117  * Option `jwt.WithTypedClaim()` and `jwk.WithTypedField()` have been added.
118    They allow a per-object custom conversion from their JSON representation
119    to a Go object, much like `RegisterCustomField`.
120
121    The difference is that whereas `RegisterCustomField` has global effect,
122    these typed fields only take effect in the call where the option was
123    explicitly passed.
124
125    `jws` and `jwe` does not have these options because
126    (1) JWS and JWE messages don't generally carry much in terms of custom data
127    (2) This requires changes in function signatures.
128
129    Only use these options when you absolutely need to. While it is a powerful
130    tool, they do have many caveats, and abusing these features will have
131    negative effects. See the documentation for details
132
133v1.2.0 30 Apr 2021
134
135This is a security fix release with minor incompatibilities from earlier version
136with regards to the behavior of `jwt.Verify()` function
137
138[Security Fix]
139  * `jwt.Verify()` had improperly used the `"alg"` header from the JWS message
140    when `jwt.WithKeySet()` option was used (potentially allowing exploits
141    described in https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/.
142    This has been fixed by ONLY trusting the keys that you provide and
143    using the `"alg"` header from the keys themselves. (#375, #381)
144
145    As a side effect, `jwt.WithKeySet()` requires that all applicable keys
146    to contain a valid `"alg"` header. Without this we cannot safely choose a key to use,
147    and hence verification will fail.
148
149    The requirement for the `"alg"` header on keys is an INCOMPATIBLE behavior.
150    This may break existing code, if the key does not already have an `"alg"` header.
151
152[New features]
153  * `jwt.Settings()` and `jwt.WithFlattenAudience(bool)` has been added
154    to control how the "aud" claim is serialized into JSON. When this
155    is enabled, all JWTs with a single "aud" claim will serialize
156    the field as a single string, instead of an array of strings with
157    a single element, i.e.:
158
159    // jwt.WithFlattenAudience(true)
160    {"aud": "foo"}
161
162    // jwt.WithFlattenAudience(false)
163    {"aud": ["foo"]}
164
165    This setting has a global effect.
166
167[Buf fixes]
168  * jwt.Validate now returns true if the value in `nbf` field is exactly
169    the same as what the clock returns (e.g. token.nbf == time.Now())
170
171v1.1.7 02 Apr 2021
172[New features]
173  * `jwk.New` `jwk.Parse`, `jwk.ParseKey` can now take a Certificate in
174    ASN.1 DER format in PEM encoding to create a JWK.
175
176[Bug fixes]
177  * Protect `jwk.New()` from invalid RSA/ECDSA keys (#360, #361)
178
179[Miscellaneous]
180  * Removed "internal/blackmagic" and separated it to its own repository.
181  * Removed unused "marshal proxy" objects in jwt
182  * Added FAQ in `jwt` package
183
184v1.1.6 28 Mar 2021
185[Bug fixes]
186  * When an object (e.g. JWT) has a null value and `AsMap()` is called,
187    `github.com/lestrrat-go/iter` would panic.
188    This should be fixed in `github.com/lestrrat-go/iter@v1.0.1` and
189    the dependency has been updated accordingly
190
191[Miscellaneous]
192  * Added How-to style docs under `docs/`
193  * github.com/goccy/go-json dependency has been updated to v0.4.8
194
195v1.1.5 12 Mar 2021
196  This is a security fix release. The JWT validation could be skipped
197  for empty values. Upgrade recommended
198
199[Security Fix]
200  * JWT validation could be skipped for empty fields (#352).
201
202[Bug fixes]
203  * Allow setting JWT "typ" fields to any value (#351).
204  * Remove stray replace directive in cmd/jwx/go.mod (#349)
205
206v1.1.4 02 Mar 2021
207[New features]
208  * jwt.ParseRequest, jwt.ParseHeader, jwt.ParseForm have been added.
209    They are convenience functions to parse JWTs out of a HTTP request.
210
211[Miscellaneous]
212  * Fix jwt.Equals() so that comparison between values containing time.Time
213    actually work
214
215  * ES256K has been made non-default. You must enable it using a build tag
216
217     go build -tags jwx_es256k ...
218
219    Your program will still compile without this tag, but it will return
220    an error during runtime, when ES256K is encountered.
221    This feature is still experimental.
222
223v1.1.3 22 Feb 2021
224[New features]
225  * Implemented ES256K signing (#337)
226    This feature should be considered experimental
227
228[Miscellaneous]
229  * Bump minimum required version to go1.15
230  * Fix examples, bench, and cmd/jwx accidentally requiring go1.16
231  * Dependencies for "github.com/goccy/go-json" has been upgraded to
232    v0.4.7
233
234v1.1.2 16 Feb 2021
235[New features]
236  * `RegisterCustomField()` has been added, which allows users to
237    specify a private claim/field/header to decode into a particular
238    object of choice, instead of map[string]interface{} or []interface{} (#332, #333)
239
240[Bug fixes]
241  * Failures for `jwk.Key.MarshalJSON()` were not properly reported (#330, #331)
242
243[Miscellaneous]
244  * `jwe.Encrypt()` now takes options. This should not matter unless you
245    were somehow depending on its method signature.
246  * Dependencies for "github.com/goccy/go-json" has been upgraded to
247    v0.4.2
248
249v1.1.1 05 Feb 2021
250[New features]
251  * Command line tool `jwx` has ben completely reworked, and it is
252    now actually useful.
253
254  * JWKs can now be serialized into PEM files with ASN.1 DER format
255    data, which is useful when you need to work between JSON and PEM
256    data formats.
257
258  * Constants in jwa package now have can be listed via functions
259    in each category.
260
261  * jwe.Encrypt and jwe.Decrypt can now handle jwk.Key objects
262
263v1.1.0 31 Jan 2021
264  v1.1.0 is a release that attempts to fix as many of the quirky APIs
265  that survived the API breaking change of v0.9.x -> v1.0.0. This is
266  hopefully the last releases that change backwards compatibility
267  in a major way, at least for some time to come.
268
269  It is unfortunate that we need to introduce API changes, but we
270  keep learning how the library is being used and the pain points
271  of using this library. Most of the times these pain points are
272  things that we initially did not think about, which in turn
273  requires us to rethink of the API.
274
275  If you do not wish to spend the time fixing your usage, make sure
276  you have your go.mod set up to not automatically track the latest
277  changes.
278
279  However, if you do decide to use the latest version, we believe
280  the API is more uniform across packages, and generally is easier
281  to understand. We hope this library helps some of you out there.
282
283[BREAKING CHANGES]
284  * `jwk.Parse(io.Reader)`, `jws.Parse(io.Reader)`, `jwt.Parse(io.Reader)`,
285    have all been changed to `Parse([]byte)`. To use an `io.Reader`,
286    use `ParseReader(io.Reader)`. `jwe.Parse` already took `[]byte`, so
287    has not been changed.
288
289    With this change, all four package `jwe`, `jwk`, `jws`, and `jwt` follow
290    the same API design, which should make things easier to navigate:
291
292      Parse([]byte)
293      ParseString(string)
294      ParseReader(io.Reader)
295
296  * `jwk.Set` is now an interface, not a struct. `jwk.Set` now has a
297    well-defined API to access and modify the `jwk.Key` objects that it holds.
298
299      Add(jwk.Key) bool
300      Clear()
301      Get(int) (jwk.Key, bool)
302      Index(jwk.Key) int
303      Len() int
304      LookupKeyID() (jwk.Key, bool) // Read the section about it below
305      Remove(jwk.Key) bool
306      Iterate(context.Context) KeyIterator
307
308  * `(jwk.Set).LookupKeyID()` no longer returns an array of `jwk.Key`.
309    Instead, only the first key matching the given key ID will be returned.
310    If you need to work with multiple keys, use `(jwk.Set).Iterate()` or
311    `(jwk.Set).Get()` to look for matching keys.
312
313  * `jwk.PublicKeyOf()` has been renamed to `jwk.PublicRawKeyOf()`,
314    which converts raw keys (e.g. `rsa.PrivateKey`) to their public
315    counter part (e.g. `rsa.PublicKey`)
316
317    `jwk.PublicKeyOf()` is now used to get the public counter part of
318    `jwk.Key` objects (e.g. `jwk.RSAPrivateKey` to `jwk.RSAPublicKey`)
319
320    `jwk.PublicSetOf()` has been added to get a new `jwk.Set` but with
321    all keys transformed to public keys via `jwk.PublicKeyOf()`
322
323  * `jwk.FetchXXXX` functions have been removed. `jwk.Fetch()` remains, but
324    it now takes `context.Context`, and doesn't support retrieving files
325    from the local file system. See `ReadFile()` for that.
326
327  * `jws.VerifyWithJKU()`, `jws.VerifyWithJWK()`, `jwk.VerifyWithJWKSet()`
328    have all been removed, but `jwk.VerifySet(jwk.Set)` has been added.
329
330  * `jws.SplitCompact(io.Reader)` has been changd to `jws.SplitCompact([]byte)`
331    Similar to `Parse()`, `SplitCompactReader(io.Reader)` and `SplitCompactString(string)`
332    have been added
333
334  * `jws.SignLiteral` has been removed.
335
336  * `jws.PayloadSigner` has been removed (but should not matter, because
337    this as internal-use only anyways)
338
339  * `jwe.WithPrettyJSONFormat` has been renamed to `jwe.WithPrettyFormat`
340
341  * `jwt.Verify` has been removed. Use `jwt.Parse()` aloing with the `jwt.WithVerify()`
342    option to perform signature verification. Validation of verified data
343    can be performed via `(jwt.Token).Validate()` method, which has been available
344    since v1.0.6
345
346  * Package `buffer` has been removed. This package should have been an internal
347    package to start with, but it was left because it had been incorporated
348    in the public API in our initial versions.
349
350  * `(jwk.Key).Get(jwk.X509CertChainKey)` no longer returns a `jwk.CertificateChain`.
351    Instead it returns a raw []*x509.Certificate.
352
353  * `(jwt.Token).Size() has been removed.
354
355  * `jwt.WithOpenIDClaims()` has been removed. Use `jwt.WithToken(openid.New())` instead.
356
357[New Features]
358  * `jwe.ReadFile(string)`, `jwk.ReadFile(string)`, `jws.ReadFile(string)`, and
359    `jwt.ReadFile(string)` have been added. In the future, we plan to introduce
360    a `WithFS` option so you can read from an arbitrary file system, but this cannot
361    be added while we keep go < 1.16 compatibility. If you want something like that,
362    you will need to put an adapter over the jwx for the time being.
363
364  * `(jwk.Key).PublicKey()` has been added. This method creates a corresponding
365    public key, with all fields (except those that shouldn't be) copied over.
366    This allows you to easily create a public key of a private key with the
367    same "kid" attribute.
368
369  * Both `jws.Verify` and `jws.Sign` methods can now handle `jwk.Key` objects, on
370    top of raw keys (e.g. rsa.PrivateKey). You no longer need to conver the
371    `jwk.Key` objects that you have in to raw keys before using these functions.
372
373  * `(jws.Header).Remove(string)`, `(jwk.Key).Remove(string)`, and
374    `(jwt.Token).Remove(string)` have been added. `jwe.Header` already had a `Remove()`
375    method, so it has not been changed.
376
377  * `(jwk.Key).Clone() has been added.
378
379[Miscellaneous]
380  * Default branch for the repository is now `main`.
381
382  * Options have been reworked. In most instances, option types should now reflect
383    better the contexts in which they can be used. For example, `jwk` now has
384    `AutoRefreshOption` and `FetchOption` instead of a single `Option`.
385
386  * JSON marshaling should be 10~30% faster by default (though they may take
387    more allocations to achieve this).
388
389    However, if performance is really bogging you down, you can try to enable
390    the optional module github.com/goccy/go-json by enabling the "jwx_goccy" tag
391
392      go build -tags jwx_goccy ...
393
394    In some cases you get an extra 40~50% performance improvement in serailization
395    https://github.com/lestrrat-go/jwx/pull/314#issue-560594020
396    https://github.com/lestrrat-go/jwx/pull/314#issuecomment-766343888
397
398  * Location for examples and benchmarks have changed: Now examples/ and bench/
399    are their respective locations, and they are each a standalone module,
400    so that in case we need extra imports (such as the case in examples)
401    they do not interfere with users who just want to include jwx in their projects.
402
403v1.0.8 15 Jan 2021
404[New features]
405  * Fixed `jws.Message` and `jws.Signature` to be properly formatted when
406    marshaled into JSON. In the same manner, `json.Unmarshal` should also
407    work as expected.
408  * Added API to programatically manipulate `jws.Message` and `jws.Signature`
409[Miscellaneous]
410  * The order of keys are now consistent as when used with `json.Marshal`.
411    Previously some objects used their own ordering, but now the code goes
412    through one extra roundtrip of `json.Unmarshal`/`json.Marshal` to preserve
413    compatible behavior. This *may* lead to slightly slower performance if
414    you are performing `json.Marshal` over and over in very quick succession.
415    Please file an issue if you have real world cases where the change
416    causes problems for you.
417  * Added more examples in various places.
418  * Tests runs have been sped up for the most oft used cases
419
420v1.0.7 11 Jan 2021
421[New features]
422  * Added jwk.AutoRefresh, which is a tool to periodically refresh JWKS. (#265)
423  * Added experimental ed25519 support (#252)
424[Bug fixes]
425  * Fix `Set()` method for jwk Keys to properly accept either `jwk.KeyUsageType`
426    or a simple string.
427[Miscellaneous]
428  * Updated dependencies
429  * Changed options to use github.com/lestrrat-go/option
430  * Various typos, unused annotations, etc, have been fixed by contributors
431  * Nobody except for the author really should care, but the underlying
432    `pdebug` utility, which is used for print debugging, has been
433    upgraded to v3, which should stop parallel test execution from throwing
434    an error when run with -race
435
436v1.0.6 17 Dec 2020
437  * Fix ECDHES ciphers where padding in AAD et al was creating
438    incomptabile values with jose tool
439  * Also fix ECDH-ES cek handling (#248)
440  * Implement direct key encoding (#213, #249)
441  * Allow JWT tokens to use default JWK if only one key is given
442    and the JWT does not necessarily specifies a key (#214)
443  * Deprecate jwt.Verify and introduce jwt.Validate. JWS verification
444    used the term Verify, which was confusing when users wanted to
445    validate the JWT token itself. (#220)
446  * JWT library optins have been explicitly typed as ValidationOption
447    and ParseOption (#220, #223)
448  * Add jwx.DecoderSettings and jwx.WithUseNumber option to globally
449    change how jwx parses JSON objects (#222)
450  * Encode x5c field as base64 with padding (#244)
451  * Add more interoperability tests against jose tool.
452  * Special thanks to anatol and imirkin!
453
454v1.0.5 - 28 Sep 2020
455  * Reinstate PrivateParams() method in jws and jwe packages.
456    These used to be available until v1.0.0, but somehow got lost during the
457    big change.
458    As a workaround for users of versions 1.0.0 to 1.0.4, you could have
459    achieved the same thing using AsMap() methods, albeit with a slight
460    performance penality (#205, #206)
461
462v1.0.4 - 15 Aug 2020
463  * Fix jwt.WithOpenIDClaims(). Looks like something got lost along
464    the way, and it never really worked. (#201 #202)
465
466v1.0.3 - 08 Jul 2020
467  * `jws.Sign`, and therefore `jwt.Sign` now accept `jwk.Key` as the
468    key to use for signature. (#199)
469  * `jwt.Sign` could sometimes return a nil error when setting bad
470    values to the protected header failed (#195)
471  * More golangci-lint cleanup (#193)
472
473v1.0.2 - 07 May 2020
474  * Since 1.0.0, we took some time to play the test coverage game.
475    The coverage is around 30% better, and we _did_ uncover some
476    inconsistencies in the API, which got promptly fixed.
477    But I'm tired of the coverage game for the time being. PR's welcome!
478  * Add jwk.AssignKeyID to automatically assign a `kid` field to a JWK
479  * Fix jwe.Encrypt / jwe.Decrypt to properly look at the `zip` field
480  * Change jwe.Message accessors to return []byte, not buffer.Buffer
481
482v1.0.1 - 04 May 2020
483  * Normalize all JWK serialization to use padding-less base64 encoding (#185)
484  * Fix edge case unmarshaling openid.AddressClaim within a openid.Token
485  * Fix edge case unmarshaling jwe.Message
486  * Export JWK key-specific constants, such as jwk.RSANKey, jwk.SymmetricOctetsKey, etc
487  * Remove some unused code
488
489v1.0.0 - 03 May 2020
490  * All packages (`jws`, `jwe`, `jwk`, `jwt`) have all been reworked from
491    the ground-up.
492    * These packages now hide the actual implementation of the main structs behind an interface.
493    * Header/Token structs must now be instantiated using proper constructors
494      (most notably, json.Unmarshal will miserably fail if you just pass
495       and empty interface via `xxx.Token` or similar)
496    * Token/Header interfaces are now more or less standardized.
497      The following API should be consistent between all relevant packages:
498      * New()
499      * Get()
500      * Set()
501      * Remove()
502      * Iterate()
503      * Walk()
504      * AsMap()
505    * Oft-used fields are no longer directly accessible:
506      e.g. `token.KeyID = v` is no longer valid. You must set using `Set`
507      (and `Remove`, if you are removing it), and use either `Get` or
508      one of the utility methods such as `token.KeyID()`
509    * Many helper functions and structs have been unexported. They were never
510      meant to be anything useful for end-users, and hopefully it does not
511      cause any problems.
512    * Most errors type/instances have been removed from the public API
513  * `jwt` package can now work with different token types, such as OpenID tokens.
514    * `token.Sign` and `token.Verify` have been changed from methods to
515      package functions `jwt.Sign` and `jwt.Verify`, to allow different
516      types of tokens to be passed to the same logic.
517    * Added a custom token type in `openid` sub-package to make it easier to
518      work with OpenID claims
519    * `jwt.Parse` (and its siblings) now accept `jwt.WithOpenIDClaims()`
520  * `jwe` API has been reworked:
521    * `MultiEncrypt` has been removed.
522    * Serializer structs have been removed. Now you just need to call
523      `jwe.Compact` or `jwe.JSON`
524  * `jwk` API has been reworked:
525    * `jwk.ParseKey` has been added
526    * `jwk.Materialize` has been renamed to `Raw()`. A new corresponding
527      method to initialize the key from a raw key (RSA/ECDSA/byte keys)
528      called `FromRaw()` has also been added, which makes a nice pair.
529  * `jws` API has been reworked
530  * CI has been changed from Travis CI to Github Actions, and tests now
531    include linting via `golangci-lint`
532
533v0.9.2 - 15 Apr 2020
534  * Maintenance release to protect users from upcoming breaking changes
535
536v0.9.1 - 27 Feb 2020
537  * Fix error wrapping in certain cases
538  * Add Claims(), Walk(), and AsMap() to iterate claims, as well as
539    getting the entire data out as a single map
540  * Work with alternate base64 encodings when decoding
541
542v0.9.0 - 22 May 2019
543  * Start tagging versions for good measure.
544