From 035b5ad1c487b837d2ffa6e787f94f0700bb11d8 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Mon, 4 Mar 2024 16:23:52 +0400 Subject: [PATCH] session: Override issuer in `Sign` Previously, `Sign` method set session token's issuer only if it had not been set yet. This could lead to the unexpected behavior on signing formed (completely or partially) token. Although this scenario is not common in NeoFS - the token is created once and then only read - this behavior does not make sense, so it's worth to be changed. Closes #546. Signed-off-by: Leonard Lyubich --- session/common.go | 6 ++---- session/container.go | 4 ++-- session/container_test.go | 18 +++++++++++++++++- session/object.go | 4 ++-- session/object_test.go | 16 ++++++++++++++++ 5 files changed, 39 insertions(+), 9 deletions(-) diff --git a/session/common.go b/session/common.go index 9c7f525f..0e432c91 100644 --- a/session/common.go +++ b/session/common.go @@ -173,10 +173,8 @@ func (x commonData) signedData(w contextWriter) []byte { } func (x *commonData) sign(signer user.Signer, w contextWriter) error { - if !x.issuerSet { - x.issuer = signer.UserID() - x.issuerSet = true - } + x.issuer = signer.UserID() + x.issuerSet = true var sig neofscrypto.Signature diff --git a/session/container.go b/session/container.go index 55584c1c..9ccbbcdb 100644 --- a/session/container.go +++ b/session/container.go @@ -137,8 +137,8 @@ func (x *Container) UnmarshalJSON(data []byte) error { return x.unmarshalJSON(data, x.readContext) } -// Sign calculates and writes signature of the [Container] data. -// Returns signature calculation errors. +// Sign calculates and writes signature of the [Container] data along with +// issuer ID using signer. Returns signature calculation errors. // // Zero [Container] is unsigned. // diff --git a/session/container_test.go b/session/container_test.go index ad761778..dc1a3279 100644 --- a/session/container_test.go +++ b/session/container_test.go @@ -563,6 +563,22 @@ func TestContainer_Sign(t *testing.T) { require.NoError(t, val.Sign(test.RandomSignerRFC6979(t))) require.True(t, val.VerifySignature()) + + t.Run("issue#546", func(t *testing.T) { + signer1 := test.RandomSignerRFC6979(t) + signer2 := test.RandomSignerRFC6979(t) + require.False(t, signer1.UserID().Equals(signer2.UserID())) + + token1 := sessiontest.Container() + require.NoError(t, token1.Sign(signer1)) + require.Equal(t, signer1.UserID(), token1.Issuer()) + + // copy token and re-sign + var token2 session.Container + token1.CopyTo(&token2) + require.NoError(t, token2.Sign(signer2)) + require.Equal(t, signer2.UserID(), token2.Issuer()) + }) } func TestContainer_SignedData(t *testing.T) { @@ -571,7 +587,7 @@ func TestContainer_SignedData(t *testing.T) { val := sessiontest.Container() val.SetIssuer(id) - signer := test.RandomSignerRFC6979(t) + signer := user.NewSigner(test.RandomSigner(t), id) test.SignedDataComponentUser(t, signer, &val) } diff --git a/session/object.go b/session/object.go index 69ae4bce..fefdbff0 100644 --- a/session/object.go +++ b/session/object.go @@ -171,8 +171,8 @@ func (x *Object) UnmarshalJSON(data []byte) error { return x.unmarshalJSON(data, x.readContext) } -// Sign calculates and writes signature of the [Object] data. -// Returns signature calculation errors. +// Sign calculates and writes signature of the [Object] data along with issuer +// ID using signer. Returns signature calculation errors. // // Zero [Object] is unsigned. // diff --git a/session/object_test.go b/session/object_test.go index 9f70c320..8b3c0c49 100644 --- a/session/object_test.go +++ b/session/object_test.go @@ -626,6 +626,22 @@ func TestObject_Sign(t *testing.T) { require.NoError(t, val.Sign(test.RandomSignerRFC6979(t))) require.True(t, val.VerifySignature()) + + t.Run("issue#546", func(t *testing.T) { + signer1 := test.RandomSignerRFC6979(t) + signer2 := test.RandomSignerRFC6979(t) + require.False(t, signer1.UserID().Equals(signer2.UserID())) + + token1 := sessiontest.Object() + require.NoError(t, token1.Sign(signer1)) + require.Equal(t, signer1.UserID(), token1.Issuer()) + + // copy token and re-sign + var token2 session.Object + token1.CopyTo(&token2) + require.NoError(t, token2.Sign(signer2)) + require.Equal(t, signer2.UserID(), token2.Issuer()) + }) } func TestObject_SignedData(t *testing.T) {