feat(deps): update go-jose to v4 (#588)

This change updates to go-jose v4, which was a new major release.

jose.ParseSigned now expects the supported signing algorithms to be passed, on which we previously did our own check. As they use a dedicated type for this, the slice of string needs to be converted. The returned error also need to be handled in a non-standard way in order to stay compatible.

For OIDC v4 we should use the jose.SignatureAlgorithm  type directly and wrap errors, instead of returned static defined errors.

Closes #583
This commit is contained in:
Tim Möhlmann 2024-04-11 18:13:30 +03:00 committed by GitHub
parent 06f37f84c1
commit 33f8df7eb2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 58 additions and 74 deletions

View file

@ -7,7 +7,7 @@ import (
"crypto/rsa"
"errors"
jose "github.com/go-jose/go-jose/v3"
jose "github.com/go-jose/go-jose/v4"
)
const (

View file

@ -7,7 +7,7 @@ import (
"reflect"
"testing"
jose "github.com/go-jose/go-jose/v3"
jose "github.com/go-jose/go-jose/v4"
)
func TestFindKey(t *testing.T) {

View file

@ -5,7 +5,7 @@ import (
"os"
"time"
jose "github.com/go-jose/go-jose/v3"
jose "github.com/go-jose/go-jose/v4"
"golang.org/x/oauth2"
"github.com/muhlemmer/gu"

View file

@ -6,7 +6,7 @@ import (
"slices"
"time"
jose "github.com/go-jose/go-jose/v3"
jose "github.com/go-jose/go-jose/v4"
)
const (

View file

@ -4,7 +4,7 @@ import (
"testing"
"time"
jose "github.com/go-jose/go-jose/v3"
jose "github.com/go-jose/go-jose/v4"
"github.com/stretchr/testify/assert"
"golang.org/x/text/language"
)

View file

@ -9,7 +9,7 @@ import (
"strings"
"time"
jose "github.com/go-jose/go-jose/v3"
jose "github.com/go-jose/go-jose/v4"
"github.com/muhlemmer/gu"
"github.com/zitadel/schema"
"golang.org/x/text/language"

View file

@ -10,7 +10,7 @@ import (
"strings"
"time"
jose "github.com/go-jose/go-jose/v3"
jose "github.com/go-jose/go-jose/v4"
str "github.com/zitadel/oidc/v3/pkg/strings"
)
@ -148,8 +148,13 @@ func CheckAuthorizedParty(claims Claims, clientID string) error {
}
func CheckSignature(ctx context.Context, token string, payload []byte, claims ClaimsSignature, supportedSigAlgs []string, set KeySet) error {
jws, err := jose.ParseSigned(token)
jws, err := jose.ParseSigned(token, toJoseSignatureAlgorithms(supportedSigAlgs))
if err != nil {
if strings.HasPrefix(err.Error(), "go-jose/go-jose: unexpected signature algorithm") {
// TODO(v4): we should wrap errors instead of returning static ones.
// This is a workaround so we keep returning the same error for now.
return ErrSignatureUnsupportedAlg
}
return ErrParse
}
if len(jws.Signatures) == 0 {
@ -159,12 +164,6 @@ func CheckSignature(ctx context.Context, token string, payload []byte, claims Cl
return ErrSignatureMultiple
}
sig := jws.Signatures[0]
if len(supportedSigAlgs) == 0 {
supportedSigAlgs = []string{"RS256"}
}
if !str.Contains(supportedSigAlgs, sig.Header.Algorithm) {
return fmt.Errorf("%w: id token signed with unsupported algorithm, expected %q got %q", ErrSignatureUnsupportedAlg, supportedSigAlgs, sig.Header.Algorithm)
}
signedPayload, err := set.VerifySignature(ctx, jws)
if err != nil {
@ -180,6 +179,18 @@ func CheckSignature(ctx context.Context, token string, payload []byte, claims Cl
return nil
}
// TODO(v4): Use the new jose.SignatureAlgorithm type directly, instead of string.
func toJoseSignatureAlgorithms(algorithms []string) []jose.SignatureAlgorithm {
out := make([]jose.SignatureAlgorithm, len(algorithms))
for i := range algorithms {
out[i] = jose.SignatureAlgorithm(algorithms[i])
}
if len(out) == 0 {
out = append(out, jose.RS256)
}
return out
}
func CheckExpiration(claims Claims, offset time.Duration) error {
expiration := claims.GetExpiration()
if !time.Now().Add(offset).Before(expiration) {