Repository: lestrrat-go/jwx
Pull request #1026 (2023-12-03 07:15:41)

v1.2.27


Patch:
diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml
index 909c8ea1..ff6b4041 100644
--- a/.github/workflows/benchmark.yml
+++ b/.github/workflows/benchmark.yml
@@ -13,7 +13,7 @@ jobs:
     name: "Test [ Go ${{ matrix.go }} / JSON Backend ${{ matrix.json_backend }} ]"
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
       - name: Cache Go modules
         uses: actions/cache@v3
         with:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d1a4854c..21086b15 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -15,7 +15,7 @@ jobs:
     name: "Test [ Go ${{ matrix.go }} / Tags ${{ matrix.go_tags }} ]"
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
       - name: Cache Go modules
         uses: actions/cache@v3
         with:
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 25dd1d4a..7bd3f7f8 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -5,14 +5,14 @@ jobs:
     name: lint
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: actions/setup-go@v4
         with:
-          go-version: 1.17
+          go-version: 1.19
           check-latest: true
       - uses: golangci/golangci-lint-action@v3
         with:
-          version: v1.45.2
+          version: v1.54.2
       - name: Run go vet
         run: |
           go vet ./...
diff --git a/.github/workflows/smoke.yml b/.github/workflows/smoke.yml
index 2b8c206f..55cec567 100644
--- a/.github/workflows/smoke.yml
+++ b/.github/workflows/smoke.yml
@@ -18,7 +18,7 @@ jobs:
     name: "Smoke [ Go ${{ matrix.go }} / Tags ${{ matrix.go_tags }} ]"
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
       - name: Cache Go modules
         uses: actions/cache@v3
         with:
diff --git a/.golangci.yml b/.golangci.yml
index f2b08452..b07a8c3b 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -10,10 +10,14 @@ linters-settings:
 linters:
   enable-all: true
   disable:
+    - contextcheck
     - cyclop
+    - depguard
+    - deadcode # deprecated
     - dupl
     - exhaustive
     - exhaustivestruct
+    - exhaustruct
     - errorlint
     - funlen
     - gci
@@ -30,22 +34,28 @@ linters:
     - gomnd
     - gomoddirectives # I think it's broken
     - gosec
+    - gosmopolitan
     - govet
     - interfacer # deprecated
+    - interfacebloat 
     - ifshort
     - ireturn # No, I _LIKE_ returning interfaces
     - lll
     - maintidx # Do this in code review
     - maligned # deprecated
     - makezero
+    - nonamedreturns
     - nakedret
     - nestif
     - nlreturn
+    - nosnakecase # deprecated
     - paralleltest
     - scopelint # deprecated
+    - structcheck # deprecated
     - tagliatelle
     - testpackage
     - thelper    # Tests are fine
+    - varcheck # deprecated
     - varnamelen # Short names are ok
     - wrapcheck
     - wsl
diff --git a/Changes b/Changes
index 428b16f6..b5ad3182 100644
--- a/Changes
+++ b/Changes
@@ -1,6 +1,18 @@
 Changes
 =======
 
+v1.2.27 - 03 Dec 2023
+[Security]
+  * [jwe] A large number in p2c parameter for PBKDF2 based encryptions could cause a DoS attack,
+    similar to https://nvd.nist.gov/vuln/detail/CVE-2022-36083.  All users should upgrade, as
+    unlike v2, v1 attempts to decrypt JWEs on JWTs by default.
+    [GHSA-7f9x-gw85-8grf]
+
+[Bug Fixes]
+  * [jwk] jwk.Set(jwk.KeyOpsKey, <jwk.KeyOperation>) now works (previously, either
+     Set(.., <string>) or Set(..., []jwk.KeyOperation{...}) worked, but not a single
+     jwk.KeyOperation
+
 v1.2.26 - 14 Jun 2023
 [Security]
   * Potential Padding Oracle Attack Vulnerability and Timing Attack Vulnerability 
diff --git a/bench/performance/go.sum b/bench/performance/go.sum
index f0b69473..572121bc 100644
--- a/bench/performance/go.sum
+++ b/bench/performance/go.sum
@@ -8,8 +8,8 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
 github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
 github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
-github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80=
-github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
+github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k=
+github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
 github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
 github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
 github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
@@ -32,8 +32,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
-golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
+golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
+golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -51,15 +51,18 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
diff --git a/examples/go.sum b/examples/go.sum
index f73bf884..309c3e92 100644
--- a/examples/go.sum
+++ b/examples/go.sum
@@ -11,8 +11,8 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
 github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
 github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
-github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80=
-github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
+github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k=
+github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
 github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
 github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
 github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
@@ -35,8 +35,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
-golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
+golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
+golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -54,17 +54,20 @@ golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
+golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
diff --git a/go.mod b/go.mod
index 17ce4268..e474f42a 100644
--- a/go.mod
+++ b/go.mod
@@ -6,13 +6,13 @@ require (
 	github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0
 	github.com/goccy/go-json v0.10.2
 	github.com/lestrrat-go/backoff/v2 v2.0.8
-	github.com/lestrrat-go/blackmagic v1.0.1
+	github.com/lestrrat-go/blackmagic v1.0.2
 	github.com/lestrrat-go/httpcc v1.0.1
 	github.com/lestrrat-go/iter v1.0.2
 	github.com/lestrrat-go/option v1.0.1
 	github.com/pkg/errors v0.9.1
 	github.com/stretchr/testify v1.8.4
-	golang.org/x/crypto v0.9.0
+	golang.org/x/crypto v0.16.0
 )
 
 retract v1.2.16 // Packaging problems.
diff --git a/go.sum b/go.sum
index f0b69473..572121bc 100644
--- a/go.sum
+++ b/go.sum
@@ -8,8 +8,8 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
 github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
 github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
-github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80=
-github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
+github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k=
+github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
 github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
 github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
 github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
@@ -32,8 +32,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
-golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
+golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
+golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -51,15 +51,18 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
diff --git a/jwe/decrypt.go b/jwe/decrypt.go
index 4fc2ef30..863f5915 100644
--- a/jwe/decrypt.go
+++ b/jwe/decrypt.go
@@ -22,6 +22,7 @@ import (
 
 // Decrypter is responsible for taking various components to decrypt a message.
 // its operation is not concurrency safe. You must provide locking yourself
+//
 //nolint:govet
 type Decrypter struct {
 	aad         []byte
diff --git a/jwe/headers.go b/jwe/headers.go
index eacbfda0..3310240f 100644
--- a/jwe/headers.go
+++ b/jwe/headers.go
@@ -69,7 +69,7 @@ func (h *stdHeaders) Clone(ctx context.Context) (Headers, error) {
 	return dst, nil
 }
 
-func (h *stdHeaders) Copy(ctx context.Context, dst Headers) error {
+func (h *stdHeaders) Copy(_ context.Context, dst Headers) error {
 	for _, pair := range h.makePairs() {
 		//nolint:forcetypeassert
 		key := pair.Key.(string)
diff --git a/jwe/interface.go b/jwe/interface.go
index c2312088..08074133 100644
--- a/jwe/interface.go
+++ b/jwe/interface.go
@@ -31,15 +31,16 @@ type stdRecipient struct {
 // For example, it is totally valid for if the protected header's
 // integrity was calculated using a non-standard line breaks:
 //
-//    {"a dummy":
-//      "protected header"}
+//	{"a dummy":
+//	  "protected header"}
 //
 // Once parsed, though, we can only serialize the protected header as:
 //
-//    {"a dummy":"protected header"}
+//	{"a dummy":"protected header"}
 //
 // which would obviously result in a contradicting integrity value
 // if we tried to re-calculate it from a parsed message.
+//
 //nolint:govet
 type Message struct {
 	authenticatedData    []byte
diff --git a/jwe/internal/keyenc/keyenc.go b/jwe/internal/keyenc/keyenc.go
index 706816ee..85932127 100644
--- a/jwe/internal/keyenc/keyenc.go
+++ b/jwe/internal/keyenc/keyenc.go
@@ -47,7 +47,7 @@ func (kw *Noop) KeyID() string {
 	return kw.keyID
 }
 
-func (kw *Noop) Encrypt(cek []byte) (keygen.ByteSource, error) {
+func (kw *Noop) Encrypt(_ []byte) (keygen.ByteSource, error) {
 	return keygen.ByteKey(kw.sharedkey), nil
 }
 
diff --git a/jwe/jwe.go b/jwe/jwe.go
index 8b45287f..d26d14c2 100644
--- a/jwe/jwe.go
+++ b/jwe/jwe.go
@@ -365,13 +365,13 @@ func parseCompact(buf []byte, storeProtectedHeaders bool) (*Message, error) {
 //
 // In that case you would register a custom field as follows
 //
-//   jwe.RegisterCustomField(`x-birthday`, timeT)
+//	jwe.RegisterCustomField(`x-birthday`, timeT)
 //
 // Then `hdr.Get("x-birthday")` will still return an `interface{}`,
 // but you can convert its type to `time.Time`
 //
-//   bdayif, _ := hdr.Get(`x-birthday`)
-//   bday := bdayif.(time.Time)
+//	bdayif, _ := hdr.Get(`x-birthday`)
+//	bday := bdayif.(time.Time)
 func RegisterCustomField(name string, object interface{}) {
 	registry.Register(name, object)
 }
diff --git a/jwe/message.go b/jwe/message.go
index 6609a692..9559877e 100644
--- a/jwe/message.go
+++ b/jwe/message.go
@@ -612,6 +612,11 @@ func doDecryptCtx(dctx *decryptCtx) ([]byte, error) {
 			if !ok {
 				return nil, errors.Errorf("unexpected type for 'p2c': %T", count)
 			}
+			// in v1, this number is hardcoded to 10000. Use v2 if you need to
+			// finetune this value
+			if countFlt > 10000 {
+				return nil, errors.Errorf("invalid value for 'p2c'")
+			}
 			salt, err := base64.DecodeString(saltB64Str)
 			if err != nil {
 				return nil, errors.Wrap(err, "failed to b64-decode 'salt'")
diff --git a/jwk/interface.go b/jwk/interface.go
index 9182f712..326097dc 100644
--- a/jwk/interface.go
+++ b/jwk/interface.go
@@ -53,7 +53,6 @@ const (
 // Such private parameters can be accessed via the `Field()` method.
 // If a resource contains a single JWK instead of a JWK set, private parameters
 // are stored in _both_ the resulting `jwk.Set` object and the `jwk.Key` object .
-//
 type Set interface {
 	// Add adds the specified key. If the key already exists in the set, it is
 	// not added.
diff --git a/jwk/jwk.go b/jwk/jwk.go
index 0ef377c9..453ecf44 100644
--- a/jwk/jwk.go
+++ b/jwk/jwk.go
@@ -39,10 +39,10 @@ func bigIntToBytes(n *big.Int) ([]byte, error) {
 // The constructor auto-detects the type of key to be instantiated
 // based on the input type:
 //
-//   * "crypto/rsa".PrivateKey and "crypto/rsa".PublicKey creates an RSA based key
-//   * "crypto/ecdsa".PrivateKey and "crypto/ecdsa".PublicKey creates an EC based key
-//   * "crypto/ed25519".PrivateKey and "crypto/ed25519".PublicKey creates an OKP based key
-//   * []byte creates a symmetric key
+//   - "crypto/rsa".PrivateKey and "crypto/rsa".PublicKey creates an RSA based key
+//   - "crypto/ecdsa".PrivateKey and "crypto/ecdsa".PublicKey creates an EC based key
+//   - "crypto/ed25519".PrivateKey and "crypto/ed25519".PublicKey creates an OKP based key
+//   - []byte creates a symmetric key
 func New(key interface{}) (Key, error) {
 	if key == nil {
 		return nil, errors.New(`jwk.New requires a non-nil key`)
@@ -636,8 +636,7 @@ func cloneKey(src Key) (Key, error) {
 // Pem serializes the given jwk.Key in PEM encoded ASN.1 DER format,
 // using either PKCS8 for private keys and PKIX for public keys.
 // If you need to encode using PKCS1 or SEC1, you must do it yourself.
-//
-// Argument must be of type jwk.Key or jwk.Set
+// The argument to this function must be of type jwk.Key or jwk.Set
 //
 // Currently only EC (including Ed25519) and RSA keys (and jwk.Set
 // comprised of these key types) are supported.
@@ -706,14 +705,13 @@ func asnEncode(key Key) (string, []byte, error) {
 //
 // In that case you would register a custom field as follows
 //
-//   jwk.RegisterCustomField(`x-birthday`, timeT)
+//	jwk.RegisterCustomField(`x-birthday`, timeT)
 //
 // Then `key.Get("x-birthday")` will still return an `interface{}`,
 // but you can convert its type to `time.Time`
 //
-//   bdayif, _ := key.Get(`x-birthday`)
-//   bday := bdayif.(time.Time)
-//
+//	bdayif, _ := key.Get(`x-birthday`)
+//	bday := bdayif.(time.Time)
 func RegisterCustomField(name string, object interface{}) {
 	registry.Register(name, object)
 }
diff --git a/jwk/key_ops.go b/jwk/key_ops.go
index 01435f3c..bc12efa5 100644
--- a/jwk/key_ops.go
+++ b/jwk/key_ops.go
@@ -13,6 +13,8 @@ func (ops *KeyOperationList) Accept(v interface{}) error {
 	switch x := v.(type) {
 	case string:
 		return ops.Accept([]string{x})
+	case KeyOperation:
+		return ops.Accept([]KeyOperation{x})
 	case []interface{}:
 		l := make([]string, len(x))
 		for i, e := range x {
diff --git a/jwk/refresh.go b/jwk/refresh.go
index 0a8f7545..e79ab7e8 100644
--- a/jwk/refresh.go
+++ b/jwk/refresh.go
@@ -18,8 +18,8 @@ import (
 // Before retrieving the jwk.Set objects, the user must pre-register the
 // URLs they intend to use by calling `Configure()`
 //
-//  ar := jwk.NewAutoRefresh(ctx)
-//  ar.Configure(url, options...)
+//	ar := jwk.NewAutoRefresh(ctx)
+//	ar.Configure(url, options...)
 //
 // Once registered, you can call `Fetch()` to retrieve the jwk.Set object.
 //
@@ -104,14 +104,14 @@ type resetTimerReq struct {
 // should mostly be set to a context that ends when the main loop/part of your
 // program exits:
 //
-// func MainLoop() {
-//   ctx, cancel := context.WithCancel(context.Background())
-//   defer cancel()
-//   ar := jwk.AutoRefresh(ctx)
-//   for ... {
-//     ...
-//   }
-// }
+//	func MainLoop() {
+//	  ctx, cancel := context.WithCancel(context.Background())
+//	  defer cancel()
+//	  ar := jwk.AutoRefresh(ctx)
+//	  for ... {
+//	    ...
+//	  }
+//	}
 func NewAutoRefresh(ctx context.Context) *AutoRefresh {
 	af := &AutoRefresh{
 		cache:        make(map[string]Set),
@@ -154,8 +154,9 @@ func (af *AutoRefresh) Remove(url string) error {
 // Note that options are treated as a whole -- you can't just update
 // one value. For example, if you did:
 //
-//   ar.Configure(url, jwk.WithHTTPClient(...))
-//   ar.Configure(url, jwk.WithRefreshInterval(...))
+//	ar.Configure(url, jwk.WithHTTPClient(...))
+//	ar.Configure(url, jwk.WithRefreshInterval(...))
+//
 // The the end result is that `url` is ONLY associated with the options
 // given in the second call to `Configure()`, i.e. `jwk.WithRefreshInterval`.
 // The other unspecified options, including the HTTP client, is set to
diff --git a/jwk/set.go b/jwk/set.go
index d5e844af..73ffcf54 100644
--- a/jwk/set.go
+++ b/jwk/set.go
@@ -296,8 +296,6 @@ func (s *set) Clone() (Set, error) {
 
 	s2.keys = make([]Key, len(s.keys))
 
-	for i := 0; i < len(s.keys); i++ {
-		s2.keys[i] = s.keys[i]
-	}
+	copy(s2.keys, s.keys)
 	return s2, nil
 }
diff --git a/jws/es256k.go b/jws/es256k.go
index fd5db88e..d421988c 100644
--- a/jws/es256k.go
+++ b/jws/es256k.go
@@ -1,3 +1,4 @@
+//go:build jwx_es256k
 // +build jwx_es256k
 
 package jws
diff --git a/jws/headers.go b/jws/headers.go
index 9ca8f656..744f0071 100644
--- a/jws/headers.go
+++ b/jws/headers.go
@@ -34,7 +34,7 @@ func (h *stdHeaders) AsMap(ctx context.Context) (map[string]interface{}, error)
 	return iter.AsMap(ctx, h)
 }
 
-func (h *stdHeaders) Copy(ctx context.Context, dst Headers) error {
+func (h *stdHeaders) Copy(_ context.Context, dst Headers) error {
 	for _, pair := range h.makePairs() {
 		//nolint:forcetypeassert
 		key := pair.Key.(string)
diff --git a/jws/interface.go b/jws/interface.go
index aeee42b4..407353c4 100644
--- a/jws/interface.go
+++ b/jws/interface.go
@@ -26,13 +26,13 @@ type DecodeCtx interface {
 // For example, the protected header `eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9`
 // decodes to
 //
-//   {"typ":"JWT",
-//     "alg":"HS256"}
+//	{"typ":"JWT",
+//	  "alg":"HS256"}
 //
 // However, when we parse this into a message, we create a jws.Header object,
 // which, when we marshal into a JSON object again, becomes
 //
-//   {"typ":"JWT","alg":"HS256"}
+//	{"typ":"JWT","alg":"HS256"}
 //
 // Notice that serialization lacks a line break and a space between `"JWT",`
 // and `"alg"`. This causes a problem when verifying the signatures AFTER
@@ -42,7 +42,7 @@ type DecodeCtx interface {
 // manifest itself. However, you may see this discrepancy when you manually
 // go through these conversions, and/or use the `jwx` tool like so:
 //
-//   jwx jws parse message.jws | jwx jws verify --key somekey.jwk --stdin
+//	jwx jws parse message.jws | jwx jws verify --key somekey.jwk --stdin
 //
 // In this scenario, the first `jwx jws parse` outputs a parsed jws.Message
 // which is marshaled into JSON. At this point the message's protected
diff --git a/jws/jws.go b/jws/jws.go
index 6908dd6b..4e00b6dd 100644
--- a/jws/jws.go
+++ b/jws/jws.go
@@ -6,8 +6,8 @@
 // If you do not care about the details, the only things that you
 // would need to use are the following functions:
 //
-//     jws.Sign(payload, algorithm, key)
-//     jws.Verify(encodedjws, algorithm, key)
+//	jws.Sign(payload, algorithm, key)
+//	jws.Verify(encodedjws, algorithm, key)
 //
 // To sign, simply use `jws.Sign`. `payload` is a []byte buffer that
 // contains whatever data you want to sign. `alg` is one of the
@@ -892,14 +892,13 @@ func parse(protected, payload, signature []byte) (*Message, error) {
 //
 // In that case you would register a custom field as follows
 //
-//   jwe.RegisterCustomField(`x-birthday`, timeT)
+//	jwe.RegisterCustomField(`x-birthday`, timeT)
 //
 // Then `hdr.Get("x-birthday")` will still return an `interface{}`,
 // but you can convert its type to `time.Time`
 //
-//   bdayif, _ := hdr.Get(`x-birthday`)
-//   bday := bdayif.(time.Time)
-//
+//	bdayif, _ := hdr.Get(`x-birthday`)
+//	bday := bdayif.(time.Time)
 func RegisterCustomField(name string, object interface{}) {
 	registry.Register(name, object)
 }
diff --git a/jwt/http.go b/jwt/http.go
index aaaf27f1..09b43155 100644
--- a/jwt/http.go
+++ b/jwt/http.go
@@ -50,14 +50,14 @@ func ParseForm(values url.Values, name string, options ...ParseOption) (Token, e
 //
 // If WithHeaderKey() is used, you must explicitly re-enable searching for "Authorization" header.
 //
-//   # searches for "Authorization"
-//   jwt.ParseRequest(req)
+//	# searches for "Authorization"
+//	jwt.ParseRequest(req)
 //
-//   # searches for "x-my-token" ONLY.
-//   jwt.ParseRequest(req, jwt.WithHeaderKey("x-my-token"))
+//	# searches for "x-my-token" ONLY.
+//	jwt.ParseRequest(req, jwt.WithHeaderKey("x-my-token"))
 //
-//   # searches for "Authorization" AND "x-my-token"
-//   jwt.ParseRequest(req, jwt.WithHeaderKey("Authorization"), jwt.WithHeaderKey("x-my-token"))
+//	# searches for "Authorization" AND "x-my-token"
+//	jwt.ParseRequest(req, jwt.WithHeaderKey("Authorization"), jwt.WithHeaderKey("x-my-token"))
 func ParseRequest(req *http.Request, options ...ParseOption) (Token, error) {
 	var hdrkeys []string
 	var formkeys []string
diff --git a/jwt/jwt.go b/jwt/jwt.go
index 13c15393..33248336 100644
--- a/jwt/jwt.go
+++ b/jwt/jwt.go
@@ -264,7 +264,7 @@ func verifyJWSWithKeySet(ctx *parseCtx, payload []byte) ([]byte, int, error) {
 			return nil, _JwsVerifyInvalid, errors.Wrapf(err, `invalid signature algorithm %s`, key.Algorithm())
 		}
 
-		// Okay, we have a valid algorithm, go go
+		// Okay, we have a valid algorithm
 		return verifyJWSWithParams(ctx, payload, alg, key)
 	}
 
@@ -548,14 +548,13 @@ func (t *stdToken) Clone() (Token, error) {
 //
 // In that case you would register a custom field as follows
 //
-//   jwt.RegisterCustomField(`x-birthday`, timeT)
+//	jwt.RegisterCustomField(`x-birthday`, timeT)
 //
 // Then `token.Get("x-birthday")` will still return an `interface{}`,
 // but you can convert its type to `time.Time`
 //
-//   bdayif, _ := token.Get(`x-birthday`)
-//   bday := bdayif.(time.Time)
-//
+//	bdayif, _ := token.Get(`x-birthday`)
+//	bday := bdayif.(time.Time)
 func RegisterCustomField(name string, object interface{}) {
 	registry.Register(name, object)
 }
diff --git a/jwt/openid/birthdate.go b/jwt/openid/birthdate.go
index ac1a81db..bb0fc30a 100644
--- a/jwt/openid/birthdate.go
+++ b/jwt/openid/birthdate.go
@@ -89,7 +89,7 @@ func (b *BirthdateClaim) Accept(v interface{}) error {
 		}
 		return nil
 	case string:
-		// yeah, yeah, regexp is slow. PR's welcome
+		// yeah, regexp is slow. PR's welcome
 		indices := birthdateRx.FindStringSubmatchIndex(v)
 		if indices == nil {
 			return errors.New(`invalid pattern for birthdate`)
diff --git a/jwt/openid/openid.go b/jwt/openid/openid.go
index 7631ea38..b4e5aefb 100644
--- a/jwt/openid/openid.go
+++ b/jwt/openid/openid.go
@@ -4,7 +4,7 @@
 // In order to use OpenID claims, you specify the token to use in the
 // jwt.Parse method
 //
-//    jwt.Parse(data, jwt.WithToken(openid.New())
+//	jwt.Parse(data, jwt.WithToken(openid.New())
 package openid
 
 import (
@@ -38,14 +38,13 @@ func (t *stdToken) Clone() (jwt.Token, error) {
 //
 // In that case you would register a custom field as follows
 //
-//   jwt.RegisterCustomField(`x-birthday`, timeT)
+//	jwt.RegisterCustomField(`x-birthday`, timeT)
 //
 // Then `token.Get("x-birthday")` will still return an `interface{}`,
 // but you can convert its type to `time.Time`
 //
-//   bdayif, _ := token.Get(`x-birthday`)
-//   bday := bdayif.(time.Time)
-//
+//	bdayif, _ := token.Get(`x-birthday`)
+//	bday := bdayif.(time.Time)
 func RegisterCustomField(name string, object interface{}) {
 	registry.Register(name, object)
 }
diff --git a/jwt/options.go b/jwt/options.go
index e905c356..2f076a00 100644
--- a/jwt/options.go
+++ b/jwt/options.go
@@ -362,7 +362,7 @@ func WithRequiredClaim(name string) ValidateOption {
 //
 // For example, in order to specify that `exp` - `iat` should be less than 10*time.Second, you would write
 //
-//    jwt.Validate(token, jwt.WithMaxDelta(10*time.Second, jwt.ExpirationKey, jwt.IssuedAtKey))
+//	jwt.Validate(token, jwt.WithMaxDelta(10*time.Second, jwt.ExpirationKey, jwt.IssuedAtKey))
 //
 // If AcceptableSkew of 2 second is specified, the above will return valid for any value of
 // `exp` - `iat`  between 8 (10-2) and 12 (10+2).
@@ -375,10 +375,9 @@ func WithMaxDelta(dur time.Duration, c1, c2 string) ValidateOption {
 //
 // For example, in order to specify that `exp` - `iat` should be greater than 10*time.Second, you would write
 //
-//    jwt.Validate(token, jwt.WithMinDelta(10*time.Second, jwt.ExpirationKey, jwt.IssuedAtKey))
+//	jwt.Validate(token, jwt.WithMinDelta(10*time.Second, jwt.ExpirationKey, jwt.IssuedAtKey))
 //
 // The validation would fail if the difference is less than 10 seconds.
-//
 func WithMinDelta(dur time.Duration, c1, c2 string) ValidateOption {
 	return WithValidator(MinDeltaIs(c1, c2, dur))
 }
@@ -387,14 +386,13 @@ func WithMinDelta(dur time.Duration, c1, c2 string) ValidateOption {
 //
 // For example, in order to validate tokens that are only valid during August, you would write
 //
-//    validator := jwt.ValidatorFunc(func(_ context.Context, t jwt.Token) error {
-//      if time.Now().Month() != 8 {
-//        return fmt.Errorf(`tokens are only valid during August!`)
-//      }
-//      return nil
-//    })
-//   err := jwt.Validate(token, jwt.WithValidator(validator))
-//
+//	 validator := jwt.ValidatorFunc(func(_ context.Context, t jwt.Token) error {
+//	   if time.Now().Month() != 8 {
+//	     return fmt.Errorf(`tokens are only valid during August!`)
+//	   }
+//	   return nil
+//	 })
+//	err := jwt.Validate(token, jwt.WithValidator(validator))
 func WithValidator(v Validator) ValidateOption {
 	return newValidateOption(identValidator{}, v)
 }
diff --git a/jwt/serialize.go b/jwt/serialize.go
index a3665ce6..c9b80e3f 100644
--- a/jwt/serialize.go
+++ b/jwt/serialize.go
@@ -43,16 +43,16 @@ type SerializeStep interface {
 // For example, to marshal the token into JSON, then apply JWS and JWE
 // in that order, you would do:
 //
-//   serialized, err := jwt.NewSerialer().
-//      Sign(jwa.RS256, key).
-//      Encrypt(jwa.RSA_OAEP, key.PublicKey).
-//      Serialize(token)
+//	serialized, err := jwt.NewSerialer().
+//	   Sign(jwa.RS256, key).
+//	   Encrypt(jwa.RSA_OAEP, key.PublicKey).
+//	   Serialize(token)
 //
 // The `jwt.Sign()` function is equivalent to
 //
-//   serialized, err := jwt.NewSerializer().
-//      Sign(...args...).
-//      Serialize(token)
+//	serialized, err := jwt.NewSerializer().
+//	   Sign(...args...).
+//	   Serialize(token)
 type Serializer struct {
 	steps []SerializeStep
 }
diff --git a/jwx.go b/jwx.go
index 24c96539..d3aae35f 100644
--- a/jwx.go
+++ b/jwx.go
@@ -5,11 +5,11 @@
 // Package jwx contains tools that deal with the various JWx (JOSE)
 // technologies such as JWT, JWS, JWE, etc in Go.
 //
-//    JWS (https://tools.ietf.org/html/rfc7515)
-//    JWE (https://tools.ietf.org/html/rfc7516)
-//    JWK (https://tools.ietf.org/html/rfc7517)
-//    JWA (https://tools.ietf.org/html/rfc7518)
-//    JWT (https://tools.ietf.org/html/rfc7519)
+//	JWS (https://tools.ietf.org/html/rfc7515)
+//	JWE (https://tools.ietf.org/html/rfc7516)
+//	JWK (https://tools.ietf.org/html/rfc7517)
+//	JWA (https://tools.ietf.org/html/rfc7518)
+//	JWT (https://tools.ietf.org/html/rfc7519)
 //
 // Examples are stored in a separate Go module (to avoid adding
 // dependencies to this module), and thus does not appear in the


Test patch:
diff --git a/jwk/jwk_test.go b/jwk/jwk_test.go
index 911fe449..b346d495 100644
--- a/jwk/jwk_test.go
+++ b/jwk/jwk_test.go
@@ -6,6 +6,7 @@ import (
 	"crypto"
 	"crypto/ecdsa"
 	"crypto/ed25519"
+	"crypto/rand"
 	"crypto/rsa"
 	"fmt"
 	"io"
@@ -31,6 +32,7 @@ import (
 	"github.com/lestrrat-go/jwx/jwk"
 	"github.com/lestrrat-go/jwx/x25519"
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 var zeroval reflect.Value
@@ -2062,3 +2064,19 @@ func TestGH664(t *testing.T) {
 		})
 	}
 }
+
+func TestGH945(t *testing.T) {
+	privateRawRsaKey, err := rsa.GenerateKey(rand.Reader, 4096)
+	require.NoError(t, err, `rsa.GenerateKey should succeed`)
+
+	newJwk, err := jwk.New(privateRawRsaKey.PublicKey)
+	require.NoError(t, err, `jwk.New should succeed`)
+
+	newJwk.Set(jwk.KeyIDKey, "foobar")
+
+	newJwk.Set(jwk.KeyUsageKey, jwk.ForSignature)
+	newJwk.Set(jwk.KeyOpsKey, jwk.KeyOpSign)
+
+	require.NotNil(t, newJwk.KeyOps(), "keyops should be non-nil")
+	require.Equal(t, newJwk.KeyOps(), jwk.KeyOperationList{jwk.KeyOpSign})
+}
diff --git a/jws/es256k_test.go b/jws/es256k_test.go
index 106af859..043cce87 100644
--- a/jws/es256k_test.go
+++ b/jws/es256k_test.go
@@ -1,3 +1,4 @@
+//go:build jwx_es256k
 // +build jwx_es256k
 
 package jws_test
diff --git a/jws/jws_test.go b/jws/jws_test.go
index 23eee7dc..374d499b 100644
--- a/jws/jws_test.go
+++ b/jws/jws_test.go
@@ -166,7 +166,7 @@ func (es *dummyECDSACryptoSigner) Public() crypto.PublicKey {
 	return es.raw.Public()
 }
 
-func (es *dummyECDSACryptoSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
+func (es *dummyECDSACryptoSigner) Sign(rand io.Reader, digest []byte, _ crypto.SignerOpts) ([]byte, error) {
 	// The implementation is the same as ecdsaCryptoSigner.
 	// This is just here to test the interface conversion
 	r, s, err := ecdsa.Sign(rand, es.raw, digest)