Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extended session #447

Merged
merged 2 commits into from
Jun 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions session/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,13 @@ func (x commonData) signedData(w contextWriter) []byte {
}

func (x *commonData) sign(signer neofscrypto.Signer, w contextWriter) error {
if err := user.IDFromSigner(&x.issuer, signer); err != nil {
return fmt.Errorf("IDFromSigner: %w", err)
}
if !x.issuerSet {
if err := user.IDFromSigner(&x.issuer, signer); err != nil {
return fmt.Errorf("IDFromSigner: %w", err)
}

x.issuerSet = true
x.issuerSet = true
}

var sig neofscrypto.Signature

Expand Down Expand Up @@ -308,6 +310,14 @@ func (x *commonData) SetAuthKey(key neofscrypto.PublicKey) {
x.authKey = x.authKey[:key.Encode(x.authKey)]
}

// SetIssuer allows to set issuer before Sign call.
// Using this method is not required when Sign is used (issuer will be derived from the signer automatically).
// When using it please ensure that the token is signed with the same signer as the issuer passed here.
func (x *commonData) SetIssuer(id user.ID) {
x.issuer = id
x.issuerSet = true
}

// AssertAuthKey asserts public key bound to the session.
//
// Zero session fails the check.
Expand Down
22 changes: 16 additions & 6 deletions session/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -526,17 +526,27 @@ func TestIssuedBy(t *testing.T) {

func TestContainer_Issuer(t *testing.T) {
var token session.Container
signer := test.RandomSignerRFC6979(t)

require.Zero(t, token.Issuer())
t.Run("signer", func(t *testing.T) {
signer := test.RandomSignerRFC6979(t)

require.NoError(t, token.Sign(signer))
require.Zero(t, token.Issuer())
require.NoError(t, token.Sign(signer))

var issuer user.ID
var issuer user.ID

require.NoError(t, user.IDFromSigner(&issuer, signer))
require.NoError(t, user.IDFromSigner(&issuer, signer))
require.True(t, token.Issuer().Equals(issuer))
})

t.Run("external", func(t *testing.T) {
var issuer user.ID
signer := test.RandomSignerRFC6979(t)
require.NoError(t, user.IDFromSigner(&issuer, signer))

require.True(t, token.Issuer().Equals(issuer))
token.SetIssuer(issuer)
require.True(t, token.Issuer().Equals(issuer))
})
}

func TestContainer_Sign(t *testing.T) {
Expand Down
5 changes: 5 additions & 0 deletions session/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ func (x *Object) Sign(signer neofscrypto.Signer) error {
return x.sign(signer, x.writeContext)
}

// SignedData returns actual payload which would be signed, if you call [Object.Sign] method.
func (x *Object) SignedData() []byte {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i can offer a pretty indicative scenario for unit test:

  1. fill token
  2. call SignedData
  3. calculate signature manually
  4. call Sign with static signer
  5. assert Verify passes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

return x.signedData(x.writeContext)
}

// VerifySignature checks if Object signature is presented and valid.
//
// Zero Object fails the check.
Expand Down
26 changes: 26 additions & 0 deletions session/object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -629,3 +629,29 @@ func TestObject_Sign(t *testing.T) {

require.True(t, val.VerifySignature())
}

func TestObject_SignedData(t *testing.T) {
var issuer user.ID

issuerSigner := test.RandomSignerRFC6979(t)
require.NoError(t, user.IDFromSigner(&issuer, issuerSigner))

var tokenSession session.Object
tokenSession.SetID(uuid.New())
tokenSession.SetExp(100500)
tokenSession.BindContainer(cidtest.ID())
tokenSession.ForVerb(session.VerbObjectPut)
tokenSession.SetAuthKey(test.RandomSignerRFC6979(t).Public())
tokenSession.SetIssuer(issuer)

sign, err := issuerSigner.Sign(tokenSession.SignedData())
require.NoError(t, err)

require.NoError(t, tokenSession.Sign(issuerSigner))
require.True(t, tokenSession.VerifySignature())

var m v2session.Token
tokenSession.WriteToV2(&m)

require.Equal(t, m.GetSignature().GetSign(), sign)
}