fix: get remote keys if no cached key matches

This commit is contained in:
Livio Amstutz 2021-09-14 11:22:24 +02:00
parent 7bb6443cd0
commit 928526286b
2 changed files with 21 additions and 11 deletions

View file

@ -88,26 +88,31 @@ func (r *remoteKeySet) VerifySignature(ctx context.Context, jws *jose.JSONWebSig
if alg == "" {
alg = r.defaultAlg
}
keys := r.keysFromCache()
if len(keys) == 0 {
return r.verifySignatureRemote(ctx, jws, keyID, alg)
}
payload, err := r.verifySignatureCached(jws, keys, keyID, alg)
payload, err := r.verifySignatureCached(jws, keyID, alg)
if payload != nil {
return payload, nil
}
if err != nil && keyID != "" || r.skipRemoteCheck {
return nil, fmt.Errorf("invalid signature: %w", err)
return nil, err
}
return r.verifySignatureRemote(ctx, jws, keyID, alg)
}
func (r *remoteKeySet) verifySignatureCached(jws *jose.JSONWebSignature, keys []jose.JSONWebKey, keyID, alg string) ([]byte, error) {
func (r *remoteKeySet) verifySignatureCached(jws *jose.JSONWebSignature, keyID, alg string) ([]byte, error) {
keys := r.keysFromCache()
if len(keys) == 0 {
return nil, nil
}
key, err := oidc.FindMatchingKey(keyID, oidc.KeyUseSignature, alg, keys...)
if err != nil {
return nil, err
//ignore error here, try with remote keys
return nil, nil //nolint:nilerr
}
return jws.Verify(&key)
payload, err := jws.Verify(&key)
if err != nil {
return nil, fmt.Errorf("signature verification failed: %w", err)
}
return payload, nil
}
func (r *remoteKeySet) verifySignatureRemote(ctx context.Context, jws *jose.JSONWebSignature, keyID, alg string) ([]byte, error) {
@ -119,7 +124,11 @@ func (r *remoteKeySet) verifySignatureRemote(ctx context.Context, jws *jose.JSON
if err != nil {
return nil, fmt.Errorf("unable to validate signature: %w", err)
}
return jws.Verify(&key)
payload, err := jws.Verify(&key)
if err != nil {
return nil, fmt.Errorf("signature verification failed: %w", err)
}
return payload, nil
}
func (r *remoteKeySet) keysFromCache() (keys []jose.JSONWebKey) {

View file

@ -39,6 +39,7 @@ var (
ErrSignatureMultiple = errors.New("id_token contains multiple signatures")
ErrSignatureUnsupportedAlg = errors.New("signature algorithm not supported")
ErrSignatureInvalidPayload = errors.New("signature does not match Payload")
ErrSignatureInvalid = errors.New("invalid signature")
ErrExpired = errors.New("token has expired")
ErrIatMissing = errors.New("issuedAt of token is missing")
ErrIatInFuture = errors.New("issuedAt of token is in the future")
@ -143,7 +144,7 @@ func CheckSignature(ctx context.Context, token string, payload []byte, claims Cl
signedPayload, err := set.VerifySignature(ctx, jws)
if err != nil {
return err
return fmt.Errorf("%w (%v)", ErrSignatureInvalid, err)
}
if !bytes.Equal(signedPayload, payload) {