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