Skip to content

Commit 22dfdca

Browse files
committed
update go-jose to v4
The biggest change between v3 and v4 is ParseSigned now requires a set of allow listed algorithms. go-oidc was already doing this ad-hoc, so the change is an improvement over the current logic.
1 parent 375c370 commit 22dfdca

File tree

6 files changed

+58
-42
lines changed

6 files changed

+58
-42
lines changed

go.mod

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
module github.com/coreos/go-oidc/v3
22

3-
go 1.19
3+
go 1.21
4+
5+
toolchain go1.22.0
46

57
require (
6-
github.com/go-jose/go-jose/v3 v3.0.1
8+
github.com/go-jose/go-jose/v4 v4.0.1
79
golang.org/x/net v0.17.0
810
golang.org/x/oauth2 v0.13.0
911
)
1012

1113
require (
1214
github.com/golang/protobuf v1.5.3 // indirect
13-
github.com/stretchr/testify v1.7.0 // indirect
14-
golang.org/x/crypto v0.14.0 // indirect
15+
golang.org/x/crypto v0.19.0 // indirect
1516
google.golang.org/appengine v1.6.8 // indirect
1617
google.golang.org/protobuf v1.31.0 // indirect
1718
)

go.sum

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,24 @@
1-
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
2-
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3-
github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA=
4-
github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
1+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3+
github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U=
4+
github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
55
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
66
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
77
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
88
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
9-
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
109
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
1110
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
11+
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
1212
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1313
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
14-
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
15-
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
16-
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
17-
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
14+
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
15+
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
1816
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
1917
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
20-
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
2118
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
22-
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
23-
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
19+
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
20+
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
2421
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
25-
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
2622
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
2723
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
2824
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
@@ -33,7 +29,6 @@ golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn
3329
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
3430
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
3531
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
36-
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3732
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3833
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
3934
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -55,6 +50,5 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
5550
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
5651
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
5752
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
58-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
59-
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
60-
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
53+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
54+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

oidc/jose.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package oidc
22

3+
import jose "github.com/go-jose/go-jose/v4"
4+
35
// JOSE asymmetric signing algorithm values as defined by RFC 7518
46
//
57
// see: https://tools.ietf.org/html/rfc7518#section-3.1
@@ -15,3 +17,16 @@ const (
1517
PS512 = "PS512" // RSASSA-PSS using SHA512 and MGF1-SHA512
1618
EdDSA = "EdDSA" // Ed25519 using SHA-512
1719
)
20+
21+
var allAlgs = []jose.SignatureAlgorithm{
22+
jose.RS256,
23+
jose.RS384,
24+
jose.RS512,
25+
jose.ES256,
26+
jose.ES384,
27+
jose.ES512,
28+
jose.PS256,
29+
jose.PS384,
30+
jose.PS512,
31+
jose.EdDSA,
32+
}

oidc/jwks.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
"sync"
1414
"time"
1515

16-
jose "github.com/go-jose/go-jose/v3"
16+
jose "github.com/go-jose/go-jose/v4"
1717
)
1818

1919
// StaticKeySet is a verifier that validates JWT against a static set of public keys.
@@ -25,7 +25,9 @@ type StaticKeySet struct {
2525

2626
// VerifySignature compares the signature against a static set of public keys.
2727
func (s *StaticKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte, error) {
28-
jws, err := jose.ParseSigned(jwt)
28+
// Algorithms are already checked by Verifier, so this parse method accepts
29+
// any algorithm.
30+
jws, err := jose.ParseSigned(jwt, allAlgs)
2931
if err != nil {
3032
return nil, fmt.Errorf("parsing jwt: %v", err)
3133
}
@@ -127,8 +129,13 @@ var parsedJWTKey contextKey
127129
func (r *RemoteKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte, error) {
128130
jws, ok := ctx.Value(parsedJWTKey).(*jose.JSONWebSignature)
129131
if !ok {
132+
// The algorithm values are already enforced by the Validator, which also sets
133+
// the context value above to pre-parsed signature.
134+
//
135+
// Practically, this codepath isn't called in normal use of this package, but
136+
// if it is, the algorithms have already been checked.
130137
var err error
131-
jws, err = jose.ParseSigned(jwt)
138+
jws, err = jose.ParseSigned(jwt, allAlgs)
132139
if err != nil {
133140
return nil, fmt.Errorf("oidc: malformed jwt: %v", err)
134141
}

oidc/jwks_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
"testing"
1818
"time"
1919

20-
jose "github.com/go-jose/go-jose/v3"
20+
jose "github.com/go-jose/go-jose/v4"
2121
)
2222

2323
type keyServer struct {
@@ -146,7 +146,7 @@ func TestKeyVerifyContextCanceled(t *testing.T) {
146146
payload := []byte("a secret")
147147

148148
good := newECDSAKey(t)
149-
jws, err := jose.ParseSigned(good.sign(t, payload))
149+
jws, err := jose.ParseSigned(good.sign(t, payload), allAlgs)
150150
if err != nil {
151151
t.Fatal(err)
152152
}
@@ -185,11 +185,11 @@ func testKeyVerify(t *testing.T, good, bad *signingKey, verification ...*signing
185185

186186
payload := []byte("a secret")
187187

188-
jws, err := jose.ParseSigned(good.sign(t, payload))
188+
jws, err := jose.ParseSigned(good.sign(t, payload), allAlgs)
189189
if err != nil {
190190
t.Fatal(err)
191191
}
192-
badJWS, err := jose.ParseSigned(bad.sign(t, payload))
192+
badJWS, err := jose.ParseSigned(bad.sign(t, payload), allAlgs)
193193
if err != nil {
194194
t.Fatal(err)
195195
}
@@ -234,11 +234,11 @@ func TestRotation(t *testing.T) {
234234
key2.keyID = "key2"
235235

236236
payload := []byte("a secret")
237-
jws1, err := jose.ParseSigned(key1.sign(t, payload))
237+
jws1, err := jose.ParseSigned(key1.sign(t, payload), allAlgs)
238238
if err != nil {
239239
t.Fatal(err)
240240
}
241-
jws2, err := jose.ParseSigned(key2.sign(t, payload))
241+
jws2, err := jose.ParseSigned(key2.sign(t, payload), allAlgs)
242242
if err != nil {
243243
t.Fatal(err)
244244
}

oidc/verify.go

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
"strings"
1313
"time"
1414

15-
jose "github.com/go-jose/go-jose/v3"
15+
jose "github.com/go-jose/go-jose/v4"
1616
"golang.org/x/oauth2"
1717
)
1818

@@ -310,7 +310,16 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
310310
return t, nil
311311
}
312312

313-
jws, err := jose.ParseSigned(rawIDToken)
313+
var supportedSigAlgs []jose.SignatureAlgorithm
314+
for _, alg := range v.config.SupportedSigningAlgs {
315+
supportedSigAlgs = append(supportedSigAlgs, jose.SignatureAlgorithm(alg))
316+
}
317+
if len(supportedSigAlgs) == 0 {
318+
// If no algorithms were specified by both the config and discovery, default
319+
// to the one mandatory algorithm "RS256".
320+
supportedSigAlgs = []jose.SignatureAlgorithm{jose.RS256}
321+
}
322+
jws, err := jose.ParseSigned(rawIDToken, supportedSigAlgs)
314323
if err != nil {
315324
return nil, fmt.Errorf("oidc: malformed jwt: %v", err)
316325
}
@@ -322,17 +331,7 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
322331
default:
323332
return nil, fmt.Errorf("oidc: multiple signatures on id token not supported")
324333
}
325-
326334
sig := jws.Signatures[0]
327-
supportedSigAlgs := v.config.SupportedSigningAlgs
328-
if len(supportedSigAlgs) == 0 {
329-
supportedSigAlgs = []string{RS256}
330-
}
331-
332-
if !contains(supportedSigAlgs, sig.Header.Algorithm) {
333-
return nil, fmt.Errorf("oidc: id token signed with unsupported algorithm, expected %q got %q", supportedSigAlgs, sig.Header.Algorithm)
334-
}
335-
336335
t.sigAlgorithm = sig.Header.Algorithm
337336

338337
ctx = context.WithValue(ctx, parsedJWTKey, jws)

0 commit comments

Comments
 (0)