From 320dd4113705b2705a21b77a8b30d530d971f277 Mon Sep 17 00:00:00 2001 From: Livio Amstutz Date: Mon, 6 Jul 2020 10:34:35 +0200 Subject: [PATCH] fix: option to ignore expiration on id_token and error handling --- pkg/rp/default_verifier.go | 26 ++++++++++++++++++-------- pkg/rp/error.go | 9 +++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/pkg/rp/default_verifier.go b/pkg/rp/default_verifier.go index 64ecaa0..db599e3 100644 --- a/pkg/rp/default_verifier.go +++ b/pkg/rp/default_verifier.go @@ -46,13 +46,20 @@ func NewDefaultVerifier(issuer, clientID string, keySet oidc.KeySet, confOpts .. return &DefaultVerifier{config: conf, keySet: keySet} } -//WithIgnoreAudience will turn off audience claim (should only be used for id_token_hints) +//WithIgnoreAudience will turn off validation for audience claim (should only be used for id_token_hints) func WithIgnoreAudience() func(*verifierConfig) { return func(conf *verifierConfig) { conf.ignoreAudience = true } } +//WithIgnoreExpiration will turn off validation for expiration claim (should only be used for id_token_hints) +func WithIgnoreExpiration() func(*verifierConfig) { + return func(conf *verifierConfig) { + conf.ignoreExpiration = true + } +} + //WithIgnoreIssuedAt will turn off iat claim verification func WithIgnoreIssuedAt() func(*verifierConfig) { return func(conf *verifierConfig) { @@ -108,6 +115,7 @@ type verifierConfig struct { clientID string nonce string ignoreAudience bool + ignoreExpiration bool iat *iatConfig acr ACRVerifier maxAge time.Duration @@ -275,10 +283,10 @@ func (v *DefaultVerifier) checkSignature(ctx context.Context, idTokenString stri return "", err } if len(jws.Signatures) == 0 { - return "", nil //TODO: error + return "", ErrSignatureMissing() } if len(jws.Signatures) > 1 { - return "", nil //TODO: error + return "", ErrSignatureMultiple() } sig := jws.Signatures[0] supportedSigAlgs := v.config.supportedSignAlgs @@ -292,16 +300,18 @@ func (v *DefaultVerifier) checkSignature(ctx context.Context, idTokenString stri signedPayload, err := v.keySet.VerifySignature(ctx, jws) if err != nil { return "", err - //TODO: } if !bytes.Equal(signedPayload, payload) { - return "", ErrSignatureInvalidPayload() //TODO: err + return "", ErrSignatureInvalidPayload() } return jose.SignatureAlgorithm(sig.Header.Algorithm), nil } func (v *DefaultVerifier) checkExpiration(expiration time.Time) error { + if v.config.ignoreExpiration { + return nil + } expiration = expiration.Round(time.Second) if !v.now().Before(expiration) { return ErrExpInvalid(expiration) @@ -362,8 +372,8 @@ func (v *DefaultVerifier) decryptToken(tokenString string) (string, error) { } func (v *DefaultVerifier) verifyAccessToken(accessToken, atHash string, sigAlgorithm jose.SignatureAlgorithm) error { - if atHash == "" { - return nil //TODO: return error + if accessToken == "" { + return nil } actual, err := oidc.ClaimHash(accessToken, sigAlgorithm) @@ -371,7 +381,7 @@ func (v *DefaultVerifier) verifyAccessToken(accessToken, atHash string, sigAlgor return err } if actual != atHash { - return nil //TODO: error + return ErrAtHash() } return nil } diff --git a/pkg/rp/error.go b/pkg/rp/error.go index 038aa4a..fa0ece9 100644 --- a/pkg/rp/error.go +++ b/pkg/rp/error.go @@ -40,9 +40,18 @@ var ( ErrAuthTimeToOld = func(maxAge, authTime time.Time) *validationError { return ValidationError("Auth Time of token must not be older than %v, but was %v (%v to old)", maxAge, authTime, maxAge.Sub(authTime)) } + ErrSignatureMissing = func() *validationError { + return ValidationError("id_token does not contain a signature") + } + ErrSignatureMultiple = func() *validationError { + return ValidationError("id_token contains multiple signatures") + } ErrSignatureInvalidPayload = func() *validationError { return ValidationError("Signature does not match Payload") } + ErrAtHash = func() *validationError { + return ValidationError("at_hash does not correspond to access token") + } ) func ValidationError(message string, args ...interface{}) *validationError {