Skip to content

Commit

Permalink
add clock skew to ValidAt
Browse files Browse the repository at this point in the history
  • Loading branch information
gerardsn committed Dec 1, 2023
1 parent 1373a01 commit 6a5e169
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 15 deletions.
18 changes: 10 additions & 8 deletions vc/vc.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,26 +183,28 @@ func (vc VerifiableCredential) JWT() jwt.Token {
return token
}

// ValidAt returns true if
// - t >= IssuanceDate and ValidFrom
// - t <= ExpirationDate and ValidUntil
// ValidAt checks that t is within the validity window of the credential.
// The skew parameter allows compensating for some clock skew (set to 0 for strict validation).
// Return true if
// - t+skew >= IssuanceDate and ValidFrom
// - t-skew <= ExpirationDate and ValidUntil
// For any value that is missing, the evaluation defaults to true
func (vc VerifiableCredential) ValidAt(t time.Time) bool {
func (vc VerifiableCredential) ValidAt(t time.Time, skew time.Duration) bool {
// IssuanceDate is a required field, but will default to the zero value when missing. (when ValidFrom != nil)
// t > IssuanceDate
if vc.IssuanceDate != nil && t.Before(*vc.IssuanceDate) {
if vc.IssuanceDate != nil && t.Add(skew).Before(*vc.IssuanceDate) {
return false
}
// t > ValidFrom
if vc.ValidFrom != nil && t.Before(*vc.ValidFrom) {
if vc.ValidFrom != nil && t.Add(skew).Before(*vc.ValidFrom) {
return false
}
// t < ExpirationDate
if vc.ExpirationDate != nil && t.After(*vc.ExpirationDate) {
if vc.ExpirationDate != nil && t.Add(-skew).After(*vc.ExpirationDate) {
return false
}
// t < ValidUntil
if vc.ValidUntil != nil && t.After(*vc.ValidUntil) {
if vc.ValidUntil != nil && t.Add(-skew).After(*vc.ValidUntil) {
return false
}
// valid
Expand Down
21 changes: 14 additions & 7 deletions vc/vc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,15 +477,22 @@ func TestVerifiableCredential_ValidAt(t *testing.T) {
hhh := time.Date(2001, 0, 0, 0, 0, 0, 0, time.UTC)

// no validity period is always true; includes missing IssuanceDate(.IsZero() == true)
assert.True(t, VerifiableCredential{}.ValidAt(time.Now()))
assert.True(t, VerifiableCredential{}.ValidAt(time.Now(), 0))

// valid on bounds
assert.True(t, VerifiableCredential{IssuanceDate: &lll, ValidFrom: &lll}.ValidAt(lll))
assert.True(t, VerifiableCredential{ExpirationDate: &lll, ValidUntil: &lll}.ValidAt(lll))
assert.True(t, VerifiableCredential{IssuanceDate: &lll, ValidFrom: &lll}.ValidAt(lll, 0))
assert.True(t, VerifiableCredential{ExpirationDate: &lll, ValidUntil: &lll}.ValidAt(lll, 0))

// invalid
assert.False(t, VerifiableCredential{IssuanceDate: &hhh, ValidFrom: &lll}.ValidAt(lll))
assert.False(t, VerifiableCredential{IssuanceDate: &lll, ValidFrom: &hhh}.ValidAt(lll))
assert.False(t, VerifiableCredential{ExpirationDate: &hhh, ValidUntil: &lll}.ValidAt(hhh))
assert.False(t, VerifiableCredential{ExpirationDate: &lll, ValidUntil: &hhh}.ValidAt(hhh))
assert.False(t, VerifiableCredential{IssuanceDate: &hhh, ValidFrom: &lll}.ValidAt(lll, 0))
assert.False(t, VerifiableCredential{IssuanceDate: &lll, ValidFrom: &hhh}.ValidAt(lll, 0))
assert.False(t, VerifiableCredential{ExpirationDate: &hhh, ValidUntil: &lll}.ValidAt(hhh, 0))
assert.False(t, VerifiableCredential{ExpirationDate: &lll, ValidUntil: &hhh}.ValidAt(hhh, 0))

// invalid made valid
skew := time.Hour * 24 * 365 * 3 // 3 years, time difference is 2 years
assert.True(t, VerifiableCredential{IssuanceDate: &hhh, ValidFrom: &lll}.ValidAt(lll, skew))
assert.True(t, VerifiableCredential{IssuanceDate: &lll, ValidFrom: &hhh}.ValidAt(lll, skew))
assert.True(t, VerifiableCredential{ExpirationDate: &hhh, ValidUntil: &lll}.ValidAt(hhh, skew))
assert.True(t, VerifiableCredential{ExpirationDate: &lll, ValidUntil: &hhh}.ValidAt(hhh, skew))
}

0 comments on commit 6a5e169

Please sign in to comment.