From a2180997209f2b8a3d280d35778ef430fa0a691c Mon Sep 17 00:00:00 2001 From: Nelz Date: Sun, 24 Feb 2019 20:30:46 -0800 Subject: [PATCH 1/2] optional claims only checked if exist --- jwt/validation.go | 6 +++--- jwt/validation_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/jwt/validation.go b/jwt/validation.go index 98f4a056..3660ed9e 100644 --- a/jwt/validation.go +++ b/jwt/validation.go @@ -94,17 +94,17 @@ func (c Claims) ValidateWithLeeway(e Expected, leeway time.Duration) error { } } - if !e.Time.IsZero() && e.Time.Add(leeway).Before(c.NotBefore.Time()) { + if c.NotBefore != nil && !e.Time.IsZero() && e.Time.Add(leeway).Before(c.NotBefore.Time()) { return ErrNotValidYet } - if !e.Time.IsZero() && e.Time.Add(-leeway).After(c.Expiry.Time()) { + if c.Expiry != nil && !e.Time.IsZero() && e.Time.Add(-leeway).After(c.Expiry.Time()) { return ErrExpired } // IssuedAt is optional but cannot be in the future. This is not required by the RFC, but // something is misconfigured if this happens and we should not trust it. - if !e.Time.IsZero() && e.Time.Add(leeway).Before(c.IssuedAt.Time()) { + if c.IssuedAt != nil && !e.Time.IsZero() && e.Time.Add(leeway).Before(c.IssuedAt.Time()) { return ErrIssuedInTheFuture } diff --git a/jwt/validation_test.go b/jwt/validation_test.go index adf2920a..6edcabd3 100644 --- a/jwt/validation_test.go +++ b/jwt/validation_test.go @@ -126,3 +126,42 @@ func TestIssuedInFuture(t *testing.T) { assert.Equal(t, err, ErrIssuedInTheFuture) } } + +func TestOptionalDateClaims(t *testing.T) { + var epoch time.Time + + testCases := []struct { + name string + claim Claims + want error + }{ + { + "no claims", + Claims{}, + nil, + }, + { + "fail nbf", + Claims{NotBefore: NewNumericDate(time.Now())}, + ErrNotValidYet, + }, + { + "fail exp", + Claims{Expiry: NewNumericDate(epoch.Add(-7 * 24 * time.Hour))}, + ErrExpired, + }, + { + "fail iat", + Claims{IssuedAt: NewNumericDate(time.Now())}, + ErrIssuedInTheFuture, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + expect := Expected{}.WithTime(epoch.Add(-24 * time.Hour)) + err := tc.claim.Validate(expect) + assert.Equal(t, tc.want, err) + }) + } +} From 93ed781edbf43bb6afcdb91ccd3126745a2376ec Mon Sep 17 00:00:00 2001 From: Nelz Date: Mon, 25 Feb 2019 06:32:20 -0800 Subject: [PATCH 2/2] single check for e.Time --- jwt/validation.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/jwt/validation.go b/jwt/validation.go index 3660ed9e..045d5dfb 100644 --- a/jwt/validation.go +++ b/jwt/validation.go @@ -94,18 +94,20 @@ func (c Claims) ValidateWithLeeway(e Expected, leeway time.Duration) error { } } - if c.NotBefore != nil && !e.Time.IsZero() && e.Time.Add(leeway).Before(c.NotBefore.Time()) { - return ErrNotValidYet - } + if !e.Time.IsZero() { + if c.NotBefore != nil && e.Time.Add(leeway).Before(c.NotBefore.Time()) { + return ErrNotValidYet + } - if c.Expiry != nil && !e.Time.IsZero() && e.Time.Add(-leeway).After(c.Expiry.Time()) { - return ErrExpired - } + if c.Expiry != nil && e.Time.Add(-leeway).After(c.Expiry.Time()) { + return ErrExpired + } - // IssuedAt is optional but cannot be in the future. This is not required by the RFC, but - // something is misconfigured if this happens and we should not trust it. - if c.IssuedAt != nil && !e.Time.IsZero() && e.Time.Add(leeway).Before(c.IssuedAt.Time()) { - return ErrIssuedInTheFuture + // IssuedAt is optional but cannot be in the future. This is not required by the RFC, but + // something is misconfigured if this happens and we should not trust it. + if c.IssuedAt != nil && e.Time.Add(leeway).Before(c.IssuedAt.Time()) { + return ErrIssuedInTheFuture + } } return nil