From ebd40dcb3405d1570300976c64803fdfb0303872 Mon Sep 17 00:00:00 2001 From: Evgenii Baidakov Date: Fri, 9 Jun 2023 14:45:19 +0400 Subject: [PATCH 1/2] session: Return actual payload for sign Signed-off-by: Evgenii Baidakov --- session/object.go | 5 +++++ session/object_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/session/object.go b/session/object.go index 3f832e0a..67e2fceb 100644 --- a/session/object.go +++ b/session/object.go @@ -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 { + return x.signedData(x.writeContext) +} + // VerifySignature checks if Object signature is presented and valid. // // Zero Object fails the check. diff --git a/session/object_test.go b/session/object_test.go index 61f6985b..c20d6ff7 100644 --- a/session/object_test.go +++ b/session/object_test.go @@ -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()) + require.NoError(t, 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) +} From 32412965a6a512e507f0713e5c0809a954b3cd2a Mon Sep 17 00:00:00 2001 From: Evgenii Baidakov Date: Fri, 9 Jun 2023 14:47:17 +0400 Subject: [PATCH 2/2] session: Add public setter for issuer Signed-off-by: Evgenii Baidakov --- session/common.go | 18 ++++++++++++++---- session/container_test.go | 22 ++++++++++++++++------ session/object_test.go | 2 +- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/session/common.go b/session/common.go index 3488180e..5f694feb 100644 --- a/session/common.go +++ b/session/common.go @@ -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 @@ -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. diff --git a/session/container_test.go b/session/container_test.go index a5c3d76b..0bd64776 100644 --- a/session/container_test.go +++ b/session/container_test.go @@ -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) { diff --git a/session/object_test.go b/session/object_test.go index c20d6ff7..818d0613 100644 --- a/session/object_test.go +++ b/session/object_test.go @@ -642,7 +642,7 @@ func TestObject_SignedData(t *testing.T) { tokenSession.BindContainer(cidtest.ID()) tokenSession.ForVerb(session.VerbObjectPut) tokenSession.SetAuthKey(test.RandomSignerRFC6979(t).Public()) - require.NoError(t, tokenSession.SetIssuer(issuer)) + tokenSession.SetIssuer(issuer) sign, err := issuerSigner.Sign(tokenSession.SignedData()) require.NoError(t, err)