Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: coreos/go-oidc
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v3.9.0
Choose a base ref
...
head repository: coreos/go-oidc
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v3.10.0
Choose a head ref
  • 4 commits
  • 9 files changed
  • 2 contributors

Commits on Feb 23, 2024

  1. fix minor typo

    bgerrity authored and ericchiang committed Feb 23, 2024
    Copy the full SHA
    65ac180 View commit details

Commits on Mar 19, 2024

  1. updated github actions

    ericchiang committed Mar 19, 2024
    Copy the full SHA
    0963f39 View commit details
  2. add staticcheck to github actions

    ericchiang committed Mar 19, 2024
    Copy the full SHA
    375c370 View commit details
  3. 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.
    ericchiang committed Mar 19, 2024
    Copy the full SHA
    22dfdca View commit details
Showing with 70 additions and 58 deletions.
  1. +11 −8 .github/workflows/test.yaml
  2. +5 −4 go.mod
  3. +11 −17 go.sum
  4. +15 −0 oidc/jose.go
  5. +10 −3 oidc/jwks.go
  6. +6 −6 oidc/jwks_test.go
  7. +1 −1 oidc/oidc.go
  8. +11 −12 oidc/verify.go
  9. +0 −7 test
19 changes: 11 additions & 8 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -9,15 +9,18 @@ on:

jobs:
build:
name: Linux
runs-on: ubuntu-latest
strategy:
matrix:
go: ['1.21', '1.22']
name: Linux Go ${{ matrix.go }}
steps:
- name: Set up Go 1.19
uses: actions/setup-go@v2
- uses: actions/checkout@v4
- name: Setup go
uses: actions/setup-go@v5
with:
go-version: '1.19'
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
go-version: ${{ matrix.go }}
- name: Test
run: "./test"
run: go test -v ./...
- name: Staticcheck
run: go run honnef.co/go/tools/cmd/staticcheck@2023.1.7 ./...
9 changes: 5 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
module github.com/coreos/go-oidc/v3

go 1.19
go 1.21

toolchain go1.22.0

require (
github.com/go-jose/go-jose/v3 v3.0.1
github.com/go-jose/go-jose/v4 v4.0.1
golang.org/x/net v0.17.0
golang.org/x/oauth2 v0.13.0
)

require (
github.com/golang/protobuf v1.5.3 // indirect
github.com/stretchr/testify v1.7.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/crypto v0.19.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/protobuf v1.31.0 // indirect
)
28 changes: 11 additions & 17 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA=
github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U=
github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
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-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
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
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
15 changes: 15 additions & 0 deletions oidc/jose.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package oidc

import jose "github.com/go-jose/go-jose/v4"

// JOSE asymmetric signing algorithm values as defined by RFC 7518
//
// see: https://tools.ietf.org/html/rfc7518#section-3.1
@@ -15,3 +17,16 @@ const (
PS512 = "PS512" // RSASSA-PSS using SHA512 and MGF1-SHA512
EdDSA = "EdDSA" // Ed25519 using SHA-512
)

var allAlgs = []jose.SignatureAlgorithm{
jose.RS256,
jose.RS384,
jose.RS512,
jose.ES256,
jose.ES384,
jose.ES512,
jose.PS256,
jose.PS384,
jose.PS512,
jose.EdDSA,
}
13 changes: 10 additions & 3 deletions oidc/jwks.go
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ import (
"sync"
"time"

jose "github.com/go-jose/go-jose/v3"
jose "github.com/go-jose/go-jose/v4"
)

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

// VerifySignature compares the signature against a static set of public keys.
func (s *StaticKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte, error) {
jws, err := jose.ParseSigned(jwt)
// Algorithms are already checked by Verifier, so this parse method accepts
// any algorithm.
jws, err := jose.ParseSigned(jwt, allAlgs)
if err != nil {
return nil, fmt.Errorf("parsing jwt: %v", err)
}
@@ -127,8 +129,13 @@ var parsedJWTKey contextKey
func (r *RemoteKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte, error) {
jws, ok := ctx.Value(parsedJWTKey).(*jose.JSONWebSignature)
if !ok {
// The algorithm values are already enforced by the Validator, which also sets
// the context value above to pre-parsed signature.
//
// Practically, this codepath isn't called in normal use of this package, but
// if it is, the algorithms have already been checked.
var err error
jws, err = jose.ParseSigned(jwt)
jws, err = jose.ParseSigned(jwt, allAlgs)
if err != nil {
return nil, fmt.Errorf("oidc: malformed jwt: %v", err)
}
12 changes: 6 additions & 6 deletions oidc/jwks_test.go
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ import (
"testing"
"time"

jose "github.com/go-jose/go-jose/v3"
jose "github.com/go-jose/go-jose/v4"
)

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

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

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

jws, err := jose.ParseSigned(good.sign(t, payload))
jws, err := jose.ParseSigned(good.sign(t, payload), allAlgs)
if err != nil {
t.Fatal(err)
}
badJWS, err := jose.ParseSigned(bad.sign(t, payload))
badJWS, err := jose.ParseSigned(bad.sign(t, payload), allAlgs)
if err != nil {
t.Fatal(err)
}
@@ -234,11 +234,11 @@ func TestRotation(t *testing.T) {
key2.keyID = "key2"

payload := []byte("a secret")
jws1, err := jose.ParseSigned(key1.sign(t, payload))
jws1, err := jose.ParseSigned(key1.sign(t, payload), allAlgs)
if err != nil {
t.Fatal(err)
}
jws2, err := jose.ParseSigned(key2.sign(t, payload))
jws2, err := jose.ParseSigned(key2.sign(t, payload), allAlgs)
if err != nil {
t.Fatal(err)
}
2 changes: 1 addition & 1 deletion oidc/oidc.go
Original file line number Diff line number Diff line change
@@ -79,7 +79,7 @@ func getClient(ctx context.Context) *http.Client {
// provider, err := oidc.NewProvider(ctx, discoveryBaseURL)
//
// This is insecure because validating the correct issuer is critical for multi-tenant
// proivders. Any overrides here MUST be carefully reviewed.
// providers. Any overrides here MUST be carefully reviewed.
func InsecureIssuerURLContext(ctx context.Context, issuerURL string) context.Context {
return context.WithValue(ctx, issuerURLKey, issuerURL)
}
23 changes: 11 additions & 12 deletions oidc/verify.go
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ import (
"strings"
"time"

jose "github.com/go-jose/go-jose/v3"
jose "github.com/go-jose/go-jose/v4"
"golang.org/x/oauth2"
)

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

jws, err := jose.ParseSigned(rawIDToken)
var supportedSigAlgs []jose.SignatureAlgorithm
for _, alg := range v.config.SupportedSigningAlgs {
supportedSigAlgs = append(supportedSigAlgs, jose.SignatureAlgorithm(alg))
}
if len(supportedSigAlgs) == 0 {
// If no algorithms were specified by both the config and discovery, default
// to the one mandatory algorithm "RS256".
supportedSigAlgs = []jose.SignatureAlgorithm{jose.RS256}
}
jws, err := jose.ParseSigned(rawIDToken, supportedSigAlgs)
if err != nil {
return nil, fmt.Errorf("oidc: malformed jwt: %v", err)
}
@@ -322,17 +331,7 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
default:
return nil, fmt.Errorf("oidc: multiple signatures on id token not supported")
}

sig := jws.Signatures[0]
supportedSigAlgs := v.config.SupportedSigningAlgs
if len(supportedSigAlgs) == 0 {
supportedSigAlgs = []string{RS256}
}

if !contains(supportedSigAlgs, sig.Header.Algorithm) {
return nil, fmt.Errorf("oidc: id token signed with unsupported algorithm, expected %q got %q", supportedSigAlgs, sig.Header.Algorithm)
}

t.sigAlgorithm = sig.Header.Algorithm

ctx = context.WithValue(ctx, parsedJWTKey, jws)
7 changes: 0 additions & 7 deletions test

This file was deleted.