From 68ed7f44415d6afe9b86215ba909b953151e3618 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Aug 2026 16:17:28 +0000 Subject: [PATCH] fix(deps): update module github.com/lestrrat-go/jwx/v4 to v4.3.0 --- go.mod | 2 +- go.sum | 4 +++ .../github.com/lestrrat-go/jwx/v4/AGENTS.md | 4 ++- vendor/github.com/lestrrat-go/jwx/v4/Changes | 14 ++++++++ .../jwx/v4/internal/json/BUILD.bazel | 2 ++ .../jwx/v4/internal/json/registry.go | 4 ++- .../jwx/v4/internal/json/skipfunc_go127.go | 15 ++++++++ .../v4/internal/json/skipfunc_pre_go127.go | 15 ++++++++ .../github.com/lestrrat-go/jwx/v4/jwe/jwe.go | 34 +++++++++++++------ .../lestrrat-go/jwx/v4/jwe/message.go | 22 ++++++------ .../lestrrat-go/jwx/v4/jwe/options.go | 12 +++++++ .../lestrrat-go/jwx/v4/jwe/options.yaml | 7 ++++ .../lestrrat-go/jwx/v4/jwe/options_gen.go | 5 +++ vendor/modules.txt | 2 +- 14 files changed, 116 insertions(+), 26 deletions(-) create mode 100644 vendor/github.com/lestrrat-go/jwx/v4/internal/json/skipfunc_go127.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v4/internal/json/skipfunc_pre_go127.go diff --git a/go.mod b/go.mod index 278d1cb25..8a6cd12fb 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/johannesboyne/gofakes3 v1.2.0 github.com/jwx-go/jwkfetch/v4 v4.0.4 github.com/lestrrat-go/httprc/v3 v3.0.6 - github.com/lestrrat-go/jwx/v4 v4.2.0 + github.com/lestrrat-go/jwx/v4 v4.3.0 github.com/magiconair/properties v1.18.11 github.com/moby/moby/api v1.55.0 github.com/peterbourgon/ff/v3 v3.4.0 diff --git a/go.sum b/go.sum index d11c0b445..38b6c08f3 100644 --- a/go.sum +++ b/go.sum @@ -346,6 +346,8 @@ github.com/lestrrat-go/httprc/v3 v3.0.6 h1:4FpLQ18KK/ypPbVU3NLWJNRvH3kcYiqKqWfKG github.com/lestrrat-go/httprc/v3 v3.0.6/go.mod h1:mSMtkZW92Z98M5YoNNztbRGxbXHql7tSitCvaxvo9l0= github.com/lestrrat-go/jwx/v4 v4.2.0 h1:YpyEnRqejbDGwOSB8rIKD2EXqfAEA/2LLN2ZZkzm9xs= github.com/lestrrat-go/jwx/v4 v4.2.0/go.mod h1:1V1wOmyFnMLltrTKXZSRMZ/GWq8UeMW1JmUaBNqD3E4= +github.com/lestrrat-go/jwx/v4 v4.3.0 h1:VbYdpYM3I0i9hkXysvbfienmu+6whbRmP1PuHYuaCFk= +github.com/lestrrat-go/jwx/v4 v4.3.0/go.mod h1:F2H0OasEOACUjSKxiN/Nn+uQeKg/Tau3bXQksXTL/iA= github.com/lestrrat-go/option/v2 v2.0.0 h1:XxrcaJESE1fokHy3FpaQ/cXW8ZsIdWcdFzzLOcID3Ss= github.com/lestrrat-go/option/v2 v2.0.0/go.mod h1:oSySsmzMoR0iRzCDCaUfsCzxQHUEuhOViQObyy7S6Vg= github.com/lestrrat-go/option/v3 v3.0.0-alpha1 h1:dvdzLwm/Ba5CJUF3jQP7w/iNYSLfy7yyh9XXNa1WjxI= @@ -450,6 +452,7 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94 github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/riverqueue/river v0.41.0 h1:E7Yfyhn74IgVaCBKsBpTHoC0LxWJvoG0jKt7Tb+lJZg= github.com/riverqueue/river v0.41.0/go.mod h1:WXiAF1/2gfUPj3H+WqQG3Q5NW5w9JmRXRTe7U9zybNc= +github.com/riverqueue/river v0.44.0/go.mod h1:ZpbxOPFScc8kkslE2rwMW6ZLZHAvK7F0KDom+3WdnL8= github.com/riverqueue/river/cmd/river v0.38.0 h1:0nD4OS9rMkR+I45dg5vJK3r91X0zmCG/kW2LXokUi9I= github.com/riverqueue/river/cmd/river v0.38.0/go.mod h1:CvffdlKGSTyoPeJ02zwOtkCypfWJRkIzaL1hmo1jyWA= github.com/riverqueue/river/riverdriver v0.41.0 h1:A5g80n6fCGu9Bp4hSq7gys7mvfOiuWkbQHuFx3iPp7w= @@ -460,6 +463,7 @@ github.com/riverqueue/river/riverdriver/riversqlite v0.38.0 h1:JBdtwZ03TT6WweQRT github.com/riverqueue/river/riverdriver/riversqlite v0.38.0/go.mod h1:aU7rA5P+pQB9JGlunvuHACWEufp4szV8+GzpfMW5Vrc= github.com/riverqueue/river/rivershared v0.41.0 h1:ax3uz5KiqfmcvRQ3kKB6iYs9Nt8J5L1RNfOKoVMWkqw= github.com/riverqueue/river/rivershared v0.41.0/go.mod h1:FaZ7bxC2DORhyFDVyHKRiZzgQPf2b/IELwPBXnHZVLA= +github.com/riverqueue/river/rivershared v0.44.0/go.mod h1:0NCQWc4H/P7ypbrLP/3gLrV6kZRl/rfq42Loyq/fRvI= github.com/riverqueue/river/rivertype v0.41.0 h1:dfscvt1asf1PpeeHTMFxQdV1ZfMoReiiMNFCPPfR0as= github.com/riverqueue/river/rivertype v0.41.0/go.mod h1:D1Ad+EaZiaXbQbJcJcfeicXJMBKno0n6UcfKI5Q7DIQ= github.com/riverqueue/rivercontrib/otelriver v0.12.0 h1:FLY0chUrXJaIsBcxR86bASKdVM/as1qs5LVLRS9/TjY= diff --git a/vendor/github.com/lestrrat-go/jwx/v4/AGENTS.md b/vendor/github.com/lestrrat-go/jwx/v4/AGENTS.md index b446052fc..97c6e9725 100644 --- a/vendor/github.com/lestrrat-go/jwx/v4/AGENTS.md +++ b/vendor/github.com/lestrrat-go/jwx/v4/AGENTS.md @@ -199,7 +199,9 @@ Use `github.com/stretchr/testify/require` for assertions (not `assert`). ## Build Tags -No build tags in v4. Optional features (signature algorithms, backend replacements) are provided as extension modules under [`github.com/jwx-go`](https://github.com/jwx-go). See [Extension Modules](docs/10-extensions.md) for the full list. +No feature build tags in v4. Optional features (signature algorithms, backend replacements) are provided as extension modules under [`github.com/jwx-go`](https://github.com/jwx-go). See [Extension Modules](docs/10-extensions.md) for the full list. + +The one exception is a Go-version compatibility shim: `internal/json/skipfunc_pre_go127.go` and `internal/json/skipfunc_go127.go` pick the json/v2 "skip this value" sentinel, which Go 1.27 renamed from `json/v2.SkipFunc` to `errors.ErrUnsupported`. Do not add feature build tags alongside it. ## Quick Reference: Common Modifications diff --git a/vendor/github.com/lestrrat-go/jwx/v4/Changes b/vendor/github.com/lestrrat-go/jwx/v4/Changes index 9cbf4da74..a546c33d4 100644 --- a/vendor/github.com/lestrrat-go/jwx/v4/Changes +++ b/vendor/github.com/lestrrat-go/jwx/v4/Changes @@ -4,6 +4,20 @@ Changes v4 has many incompatibilities with v3. To see the full list of differences between v3 and v4, please read the [Changes-v4.md file](./Changes-v4.md). Coding Agents should read [MIGRATION-v4.md](./MICRATION-v4.md) +v4.3.0 18 August 2026 + * [jwe] Correct the JSON `"aad"` member so it contains only + BASE64URL of the external Additional Authenticated Data, rather than the + combined value used as the content-encryption AAD. Add + `jwe.WithAuthenticateData` for encrypting JSON JWEs with external AAD; + the value is included in the shared AEAD input for all recipients, and + compact serialization rejects non-empty external AAD. (#2275, #2277) + * Fix the build under Go 1.27. Go 1.27 removed `encoding/json/v2.SkipFunc` + and gave its role to `errors.ErrUnsupported`, which broke compilation of + `internal/json` for anyone on the new toolchain. The sentinel is now + selected by a Go-version build tag, so both Go 1.26 (with + `GOEXPERIMENT=jsonv2`) and Go 1.27 build from the same source. No public + API or behavior change. + v4.2.0 24 July 2026 * [jwk] `jwk.Parse` (and `Set.UnmarshalJSON`) no longer fails an entire JWK Set when a single entry in the "keys" array cannot be parsed. By diff --git a/vendor/github.com/lestrrat-go/jwx/v4/internal/json/BUILD.bazel b/vendor/github.com/lestrrat-go/jwx/v4/internal/json/BUILD.bazel index 0b622a39d..9a668d1b2 100644 --- a/vendor/github.com/lestrrat-go/jwx/v4/internal/json/BUILD.bazel +++ b/vendor/github.com/lestrrat-go/jwx/v4/internal/json/BUILD.bazel @@ -5,6 +5,8 @@ go_library( srcs = [ "json.go", "registry.go", + "skipfunc_go127.go", + "skipfunc_pre_go127.go", ], importpath = "github.com/lestrrat-go/jwx/v4/internal/json", visibility = ["//:__subpackages__"], diff --git a/vendor/github.com/lestrrat-go/jwx/v4/internal/json/registry.go b/vendor/github.com/lestrrat-go/jwx/v4/internal/json/registry.go index b8be182b6..63c2de98d 100644 --- a/vendor/github.com/lestrrat-go/jwx/v4/internal/json/registry.go +++ b/vendor/github.com/lestrrat-go/jwx/v4/internal/json/registry.go @@ -70,7 +70,9 @@ func (dec *TypedDecoder[T]) Decode(data []byte) (any, error) { var useNumberUnmarshalers = jsonv2.WithUnmarshalers( jsonv2.UnmarshalFromFunc(func(dec *jsontext.Decoder, val *any) error { if dec.PeekKind() != '0' { - return jsonv2.SkipFunc + // the sentinel is spelled differently before and after go1.27; + // see skipfunc_go127.go / skipfunc_pre_go127.go + return errSkipFunc } raw, err := dec.ReadValue() if err != nil { diff --git a/vendor/github.com/lestrrat-go/jwx/v4/internal/json/skipfunc_go127.go b/vendor/github.com/lestrrat-go/jwx/v4/internal/json/skipfunc_go127.go new file mode 100644 index 000000000..fedd48645 --- /dev/null +++ b/vendor/github.com/lestrrat-go/jwx/v4/internal/json/skipfunc_go127.go @@ -0,0 +1,15 @@ +//go:build go1.27 + +package json + +import ( + "errors" +) + +// errSkipFunc is the sentinel a marshal/unmarshal function returns to decline +// handling a value, so that the next applicable function (or the default +// behavior) is used instead. +// +// Go 1.27 removed json/v2.SkipFunc and gave the role to errors.ErrUnsupported, +// which json/v2 now matches with errors.Is rather than by identity. +var errSkipFunc = errors.ErrUnsupported diff --git a/vendor/github.com/lestrrat-go/jwx/v4/internal/json/skipfunc_pre_go127.go b/vendor/github.com/lestrrat-go/jwx/v4/internal/json/skipfunc_pre_go127.go new file mode 100644 index 000000000..1de560980 --- /dev/null +++ b/vendor/github.com/lestrrat-go/jwx/v4/internal/json/skipfunc_pre_go127.go @@ -0,0 +1,15 @@ +//go:build !go1.27 + +package json + +import ( + jsonv2 "encoding/json/v2" +) + +// errSkipFunc is the sentinel a marshal/unmarshal function returns to decline +// handling a value, so that the next applicable function (or the default +// behavior) is used instead. +// +// Go 1.26 spells it json/v2.SkipFunc and compares it by identity +// (`err == SkipFunc`), so it has to be returned verbatim. +var errSkipFunc = jsonv2.SkipFunc diff --git a/vendor/github.com/lestrrat-go/jwx/v4/jwe/jwe.go b/vendor/github.com/lestrrat-go/jwx/v4/jwe/jwe.go index 3f36af240..f6f491f26 100644 --- a/vendor/github.com/lestrrat-go/jwx/v4/jwe/jwe.go +++ b/vendor/github.com/lestrrat-go/jwx/v4/jwe/jwe.go @@ -797,13 +797,14 @@ func (dc *decryptContext) decryptContent(msg *Message, alg jwa.KeyEncryptionAlgo // encryptContext holds the state during JWE encryption, similar to JWS signContext type encryptContext struct { - calg jwa.ContentEncryptionAlgorithm - compression jwa.CompressionAlgorithm - format int - pbes2Count int - builders []*recipientBuilder - protected Headers - builderBuf [1]recipientBuilder // inline storage for common single-recipient case + calg jwa.ContentEncryptionAlgorithm + compression jwa.CompressionAlgorithm + format int + pbes2Count int + authenticatedData []byte + builders []*recipientBuilder + protected Headers + builderBuf [1]recipientBuilder // inline storage for common single-recipient case } var encryptContextPool = pool.New(allocEncryptContext, freeEncryptContext) @@ -821,6 +822,7 @@ func freeEncryptContext(ec *encryptContext) *encryptContext { ec.compression = jwa.NoCompress() ec.format = fmtCompact ec.pbes2Count = 0 + ec.authenticatedData = nil ec.builders = ec.builders[:0] ec.protected = nil ec.builderBuf[0] = recipientBuilder{} @@ -864,6 +866,8 @@ func (ec *encryptContext) ProcessOptions(options []EncryptOption) error { ec.calg = option.MustGet[jwa.ContentEncryptionAlgorithm](opt) case identCompress{}: ec.compression = option.MustGet[jwa.CompressionAlgorithm](opt) + case identAuthenticateData{}: + ec.authenticatedData = option.MustGet[[]byte](opt) case identMergeProtectedHeaders{}: mergeProtected = option.MustGet[bool](opt) case identProtectedHeaders{}: @@ -892,6 +896,10 @@ func (ec *encryptContext) ProcessOptions(options []EncryptOption) error { } } + if len(ec.authenticatedData) > 0 && ec.format == fmtCompact { + return fmt.Errorf(`cannot use compact serialization with external authenticated data (use WithJSON())`) + } + if useRawCEK { if len(ec.builders) != 1 { return fmt.Errorf(`multiple recipients for ECDH-ES/DIRECT mode are not supported`) @@ -1082,12 +1090,13 @@ func (ec *encryptContext) EncryptMessage(payload []byte, cek []byte) ([]byte, er } } - aad, err := protected.Encode() + protectedAAD, err := protected.Encode() if err != nil { return nil, fmt.Errorf(`failed to base64 encode protected headers: %w`, err) } - iv, ciphertext, tag, err := contentcrypt.Encrypt(cek, payload, aad) + contentAAD := concatAAD(protectedAAD, base64.Encode(ec.authenticatedData)) + iv, ciphertext, tag, err := contentcrypt.Encrypt(cek, payload, contentAAD) if err != nil { return nil, fmt.Errorf(`failed to encrypt payload: %w`, err) } @@ -1097,7 +1106,7 @@ func (ec *encryptContext) EncryptMessage(payload []byte, cek []byte) ([]byte, er // were copied into protected above), so we can build the compact // serialization directly from the raw parts. if ec.format == fmtCompact { - return jwebb.JoinCompact(base64.DefaultEncoder(), aad, recipients[0].EncryptedKey(), iv, ciphertext, tag), nil + return jwebb.JoinCompact(base64.DefaultEncoder(), protectedAAD, recipients[0].EncryptedKey(), iv, ciphertext, tag), nil } msg := msgPool.Get() @@ -1118,6 +1127,11 @@ func (ec *encryptContext) EncryptMessage(payload []byte, cek []byte) ([]byte, er if err := msg.Set(TagKey, tag); err != nil { return nil, fmt.Errorf(`failed to set %s: %w`, TagKey, err) } + if len(ec.authenticatedData) > 0 { + if err := msg.Set(AuthenticatedDataKey, ec.authenticatedData); err != nil { + return nil, fmt.Errorf(`failed to set %s: %w`, AuthenticatedDataKey, err) + } + } switch ec.format { case fmtJSON: diff --git a/vendor/github.com/lestrrat-go/jwx/v4/jwe/message.go b/vendor/github.com/lestrrat-go/jwx/v4/jwe/message.go index 6012b362d..ca953ec48 100644 --- a/vendor/github.com/lestrrat-go/jwx/v4/jwe/message.go +++ b/vendor/github.com/lestrrat-go/jwx/v4/jwe/message.go @@ -228,31 +228,29 @@ func (m *Message) MarshalJSON() ([]byte, error) { fields = append(fields, jsonKV{Key: InitializationVectorKey, Value: v}) } - var encodedProtectedHeaders []byte if h := m.ProtectedHeaders(); h != nil { v, err := h.Encode() if err != nil { return nil, fmt.Errorf(`failed to encode protected headers: %w`, err) } - encodedProtectedHeaders = v - if len(encodedProtectedHeaders) <= 2 { // '{}' - encodedProtectedHeaders = nil - } else { + if len(v) > 2 { // '{}' fields = append(fields, jsonKV{ Key: ProtectedHeadersKey, - Value: fmt.Sprintf("%q", encodedProtectedHeaders), + Value: fmt.Sprintf("%q", v), }) } } if aad := m.AuthenticatedData(); len(aad) > 0 { - aad = base64.Encode(aad) - if encodedProtectedHeaders != nil { - aad = concatAAD(encodedProtectedHeaders, aad) - } - - v, err := marshalField(aad) + // RFC 7516 §7.2.1: the "aad" member is BASE64URL(JWE AAD) — the + // external Additional Authenticated Data on its own. The protected + // header is prepended to the AAD only when building the AEAD input + // (concatAAD, in the encrypt/decrypt paths), never in the serialized + // member. Encode to a base64url string like the ciphertext/iv/tag + // members above so marshalField does not base64-encode the raw bytes + // a second time (which also used the padded std alphabet). + v, err := marshalField(base64.EncodeToString(aad)) if err != nil { return nil, fmt.Errorf(`failed to encode %s field: %w`, AuthenticatedDataKey, err) } diff --git a/vendor/github.com/lestrrat-go/jwx/v4/jwe/options.go b/vendor/github.com/lestrrat-go/jwx/v4/jwe/options.go index c2575926b..89e6c89d5 100644 --- a/vendor/github.com/lestrrat-go/jwx/v4/jwe/options.go +++ b/vendor/github.com/lestrrat-go/jwx/v4/jwe/options.go @@ -1,6 +1,8 @@ package jwe import ( + "bytes" + "github.com/lestrrat-go/jwx/v4/jwa" "github.com/lestrrat-go/jwx/v4/jwk" "github.com/lestrrat-go/option/v3" @@ -81,6 +83,16 @@ func WithProtectedHeaders(h Headers) EncryptOption { return &encryptOption{option.New(identProtectedHeaders{}, cloned)} } +// WithAuthenticateData specifies the external Additional Authenticated Data +// to use when encrypting a JSON JWE. +// +// The data is copied before it is stored in the option. External Additional +// Authenticated Data is not supported by compact serialization; pass +// WithJSON() to select JSON serialization. +func WithAuthenticateData(aad []byte) EncryptOption { + return &encryptOption{option.New(identAuthenticateData{}, bytes.Clone(aad))} +} + type withKey struct { alg jwa.KeyAlgorithm key any diff --git a/vendor/github.com/lestrrat-go/jwx/v4/jwe/options.yaml b/vendor/github.com/lestrrat-go/jwx/v4/jwe/options.yaml index 655e528a9..4099522f7 100644 --- a/vendor/github.com/lestrrat-go/jwx/v4/jwe/options.yaml +++ b/vendor/github.com/lestrrat-go/jwx/v4/jwe/options.yaml @@ -55,6 +55,13 @@ options: skip_option: true - ident: ProtectedHeaders skip_option: true + - ident: AuthenticateData + skip_option: true + interface: EncryptOption + argument_type: '[]byte' + comment: | + WithAuthenticateData specifies the external Additional Authenticated Data + to use when encrypting a JSON JWE. - ident: PerRecipientHeaders skip_option: true - ident: KeyProvider diff --git a/vendor/github.com/lestrrat-go/jwx/v4/jwe/options_gen.go b/vendor/github.com/lestrrat-go/jwx/v4/jwe/options_gen.go index 527483672..b52b248fa 100644 --- a/vendor/github.com/lestrrat-go/jwx/v4/jwe/options_gen.go +++ b/vendor/github.com/lestrrat-go/jwx/v4/jwe/options_gen.go @@ -156,6 +156,7 @@ type withKeySetSuboption struct { func (*withKeySetSuboption) withKeySetSuboption() {} +type identAuthenticateData struct{} type identCBCBufferSize struct{} type identCEK struct{} type identCompress struct{} @@ -178,6 +179,10 @@ type identProtectedHeaders struct{} type identRequireKid struct{} type identSerialization struct{} +func (identAuthenticateData) String() string { + return "WithAuthenticateData" +} + func (identCBCBufferSize) String() string { return "WithCBCBufferSize" } diff --git a/vendor/modules.txt b/vendor/modules.txt index a049ce69a..25ed172b8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -569,7 +569,7 @@ github.com/lestrrat-go/httprc/v3 github.com/lestrrat-go/httprc/v3/errsink github.com/lestrrat-go/httprc/v3/proxysink github.com/lestrrat-go/httprc/v3/tracesink -# github.com/lestrrat-go/jwx/v4 v4.2.0 +# github.com/lestrrat-go/jwx/v4 v4.3.0 ## explicit; go 1.26.0 github.com/lestrrat-go/jwx/v4 github.com/lestrrat-go/jwx/v4/cert