Skip to content

Commit

Permalink
session: Check expiration regardless of lifetime field availability
Browse files Browse the repository at this point in the history
Previously, any token w/o lifetime field was always considered as
invalid (expired in particular). In the protocol, the lifetime field's
absence is equivalent to all zero claims. Thus, `InvalidAt` and
`ExpiredAt` methods behaved correctly for all cases except default one.
At the same time, if user explicitly set all lifetime claims to zero -
token was not invalid at the epoch #0.

From now skipping a lifetime field in a token message is equivalent to a
field with all zeros. This change will only affect epoch #0 and will be
invisible in practice since the NeoFS network starts from epoch #1. In
addition, the internal structure of the type has been simplified.

Signed-off-by: Leonard Lyubich <[email protected]>
  • Loading branch information
cthulhu-rider committed Sep 18, 2024
1 parent 2a68580 commit f17fc15
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 31 deletions.
19 changes: 7 additions & 12 deletions session/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ type commonData struct {

issuer user.ID

lifetimeSet bool
iat, nbf, exp uint64

authKey []byte
Expand All @@ -35,7 +34,6 @@ func (x commonData) copyTo(dst *commonData) {

dst.issuer = x.issuer

dst.lifetimeSet = x.lifetimeSet
dst.iat = x.iat
dst.nbf = x.nbf
dst.exp = x.exp
Expand Down Expand Up @@ -83,11 +81,7 @@ func (x *commonData) readFromV2(m session.Token, checkFieldPresence bool, r cont
}

lifetime := body.GetLifetime()
if x.lifetimeSet = lifetime != nil; x.lifetimeSet {
x.iat = lifetime.GetIat()
x.nbf = lifetime.GetNbf()
x.exp = lifetime.GetExp()
} else if checkFieldPresence {
if checkFieldPresence && lifetime == nil {
return errors.New("missing token lifetime")
}

Expand All @@ -113,6 +107,10 @@ func (x *commonData) readFromV2(m session.Token, checkFieldPresence bool, r cont
return errors.New("missing body signature")
}

x.iat = lifetime.GetIat()
x.nbf = lifetime.GetNbf()
x.exp = lifetime.GetExp()

return nil
}

Expand All @@ -137,7 +135,7 @@ func (x commonData) fillBody(w contextWriter) *session.TokenBody {
body.SetOwnerID(&issuer)
}

if x.lifetimeSet {
if x.iat != 0 || x.nbf != 0 || x.exp != 0 {
var lifetime session.TokenLifetime
lifetime.SetIat(x.iat)
lifetime.SetNbf(x.nbf)
Expand Down Expand Up @@ -243,7 +241,6 @@ func (x *commonData) unmarshalJSON(data []byte, r contextReader) error {
// See also ExpiredAt.
func (x *commonData) SetExp(exp uint64) {
x.exp = exp
x.lifetimeSet = true
}

// SetNbf sets "nbf" (not before) claim which identifies the time (in NeoFS
Expand All @@ -256,7 +253,6 @@ func (x *commonData) SetExp(exp uint64) {
// See also InvalidAt.
func (x *commonData) SetNbf(nbf uint64) {
x.nbf = nbf
x.lifetimeSet = true
}

// SetIat sets "iat" (issued at) claim which identifies the time (in NeoFS
Expand All @@ -268,11 +264,10 @@ func (x *commonData) SetNbf(nbf uint64) {
// See also InvalidAt.
func (x *commonData) SetIat(iat uint64) {
x.iat = iat
x.lifetimeSet = true
}

func (x commonData) expiredAt(epoch uint64) bool {
return !x.lifetimeSet || x.exp < epoch
return x.exp < epoch
}

// InvalidAt asserts "exp", "nbf" and "iat" claims.
Expand Down
28 changes: 9 additions & 19 deletions session/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,15 @@ func Test_commonData_copyTo(t *testing.T) {
usr := usertest.User()

data := commonData{
idSet: true,
id: uuid.New(),
issuer: usr.UserID(),
lifetimeSet: true,
iat: 1,
nbf: 2,
exp: 3,
authKey: []byte{1, 2, 3, 4},
sigSet: true,
sig: sig,
idSet: true,
id: uuid.New(),
issuer: usr.UserID(),
iat: 1,
nbf: 2,
exp: 3,
authKey: []byte{1, 2, 3, 4},
sigSet: true,
sig: sig,
}

t.Run("copy", func(t *testing.T) {
Expand Down Expand Up @@ -130,7 +129,6 @@ func Test_commonData_copyTo(t *testing.T) {
var dst commonData
data.copyTo(&dst)

require.Equal(t, data.lifetimeSet, dst.lifetimeSet)
require.Equal(t, data.iat, dst.iat)
require.Equal(t, data.nbf, dst.nbf)
require.Equal(t, data.exp, dst.exp)
Expand All @@ -139,7 +137,6 @@ func Test_commonData_copyTo(t *testing.T) {
dst.SetIat(200)
dst.SetNbf(300)

require.Equal(t, data.lifetimeSet, dst.lifetimeSet)
require.NotEqual(t, data.iat, dst.iat)
require.NotEqual(t, data.nbf, dst.nbf)
require.NotEqual(t, data.exp, dst.exp)
Expand All @@ -148,26 +145,21 @@ func Test_commonData_copyTo(t *testing.T) {
t.Run("overwrite lifetime", func(t *testing.T) {
// lifetime is not set
local := commonData{}
require.False(t, local.lifetimeSet)

// lifetime is set
var dst commonData
dst.SetExp(100)
dst.SetIat(200)
dst.SetNbf(300)
require.True(t, dst.lifetimeSet)

local.copyTo(&dst)
require.False(t, local.lifetimeSet)
require.False(t, dst.lifetimeSet)

emptyWriter := func() session.TokenContext {
return &session.ContainerSessionContext{}
}
require.True(t, bytes.Equal(local.marshal(emptyWriter), dst.marshal(emptyWriter)))

// check both are equal
require.Equal(t, local.lifetimeSet, dst.lifetimeSet)
require.Equal(t, local.iat, dst.iat)
require.Equal(t, local.nbf, dst.nbf)
require.Equal(t, local.exp, dst.exp)
Expand All @@ -178,8 +170,6 @@ func Test_commonData_copyTo(t *testing.T) {
dst.SetNbf(300)

// check that affects only dst
require.False(t, local.lifetimeSet)
require.True(t, dst.lifetimeSet)
require.NotEqual(t, local.iat, dst.iat)
require.NotEqual(t, local.nbf, dst.nbf)
require.NotEqual(t, local.exp, dst.exp)
Expand Down
1 change: 1 addition & 0 deletions session/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ func TestContainer_AppliedTo(t *testing.T) {

func TestContainer_InvalidAt(t *testing.T) {
var x session.Container
require.False(t, x.InvalidAt(0))

nbf := rand.Uint64()
if nbf == math.MaxUint64 {
Expand Down
1 change: 1 addition & 0 deletions session/object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ func TestObject_AssertObject(t *testing.T) {

func TestObject_InvalidAt(t *testing.T) {
var x session.Object
require.False(t, x.InvalidAt(0))

nbf := rand.Uint64()
if nbf == math.MaxUint64 {
Expand Down

0 comments on commit f17fc15

Please sign in to comment.