From e88a6ee028d6c841f6e9a7789f9098c537dda440 Mon Sep 17 00:00:00 2001 From: alexvanin Date: Fri, 17 Jan 2020 12:37:04 +0300 Subject: [PATCH 1/3] session: Add owner's public key into session token We want to remove all innner ring queries to authenticate owner by public keys. Therefore we put public keys into session token. Later public keys could be gathered with NeoID or other centre of authority. --- session/types.pb.go | Bin 21404 -> 22862 bytes session/types.proto | 2 ++ 2 files changed, 2 insertions(+) diff --git a/session/types.pb.go b/session/types.pb.go index f597612920bb1e6cbb44068aed1b2e3650ff2995..5b2f5c4a1e079f2dc57e7c7804dfd064fe66a275 100644 GIT binary patch delta 2668 zcmZWr&u<$=6qel*x~^KGrl9bnblM{1sCKizcQ$H}im0N3sHoHflCi4U-PvL_v8~vs zj!?B6xp3M85^&+f4G{hdxN?BMf&=P_zW`>w&xxHThsk8-z4v|Zd+*KWho2gM{?_>Q z?uC~hj-Ke@y$|X~7j|!NZHZ65$o2;LNBVFg)MPTs2WqMd@pLf#T#TL$^+C&7u@J{U zy?*`5nT=Ov=Rl7;L$$AWmS*+sGaHRbeevwK^R0{DpRKpAoxilJr%QwOrZE2hp1aXn zp4Gpc+nE1x=}My+$@-u5NtG8J;m$&BR~^_ja62u>oq3`CLq>K@GrN{JNfH?4ILB=q z+r7qZk=lKTy^C<6vL^}=6kwze02oy>4^}SxB1DQ2JCZArJiGU}0#m_0hmCUWt&i9R zPW%W6gd_PBG`!N91|TEtiNS{e5n>d$mS7(uPrZViAw-N@nF4_%BOLjF&OqM99tg7( z2`Z$f07jC9-B+^`WXOX1l*Pz^5W~9!y%6*~rVC=kj6qexEdqYd6tEI4fqm{nDo7|3 z15la5fs==u5;3S!2*%7Ur?}u!06)iV3A6&SjU-0f1ep`xBxO5E9l@Dv&HjK}V$OHX zHDrwtBZ4Wp#;g_4T-+v90Zhp^P(%po|6Y5&GVxui36l^gArM`r2cdEVQwYz#3?NjJ zGZ;{q2OHT#t`cj(6@e507LBJmz=v}H5nSw1=0)#Di>{$+P*c(rc?YD8dhlG4Dw5(j zv3EHl>6}Z1JehM9I<2AaI`c8;8q z?GvM*8T?pczMd=q%VWmVMCIFNB(Vt09K6f}V@E4RxC|F@1rPQzUlKcEM{lnNCI{RH zmlUgyN-{&X5>Je_79m531XRs{9ES_3Dj-?UtU_D4I7;~RfGgRvV=}V9YS1hK-!R5@ z;lM{CCwaaO*fU$cVH)_9Eup9tjwH1`qGu6u9Oaxk5`$u#w+P}Uv;jUJ4)!F;bEOuX z10R+ddzAz#mNkZ~CB;Qle&RT3oR6H1Mpe0@(b%i}=q!*uiUjfrXp@G-NdRH^9IW%B zSVD~w0tEH*H{ZBoipCZ(A*~+#E;5Wizy8+WFKrJ>v8RXa{aed_6*k3t!WCb(9H$%| zh{65h?o4d&oHDDwyCJR)MECSf4?g|PmQz1?d;Rh<^2)`J@3xZ{fsd{?ji=)bx?TIL zxHG-e8}!AFNhb8o$+LO$`e)9EFFK!O{iq`{OZq?!A8WCi9TIc)OgtMQvm_fg-)TC} z>c85b&VRo7&DFJBO|+2pwXJ?*GXMSkX0!gvJ6}zViyDvhusESsN9?O7y4~w%hf`Cf z@n|x=H!Sq53lW$~J{ljMaO$06-}U+(!CbB2+sARNj7E(6^R?)CV}AMLuh;$uafHLQ delta 2045 zcmZXVy^0h;6opw~!4*~m1#w~61vd~}r24PAIxg-@?#G5Ul!6ivvzjQ*-OybM8HLZ_SUZgU??MzCArYIs5PP^259F{qrYh+ZV^r zcK2_dAMU>1-W*(O+wJ!|AD1>=oSC@|WsOZ)8*_2v$jp_))R%Q&9mld)z=&&Wip358 ze0*K@iPZr;u-3lV1DKVCU~02znaA=q$F8g`s2)5E#=t(Oluu<3!p1X@S7Sk-gaFUv zU>F1eL5))f&BUHUmRUcBs$ldSkl0)+S88_HlYpk;S=TT~w*YkywlqvwCX$?D377zi zl(X7PcFWv@H>yIisM)t-==c$dwjecNNL)!D@EIixNh&W#)PN+0>>3b8ENz!dSj^lh z0$*KR5+``dK5~h|>(v-US?nHcrzRo04j)?>vR2S_)TUKp_+0se+;3>*ghyN}>EUk( z_ICUG?!Bd;b+}h5mU86ou(XsRHPx>@DOSJ)PCGmku{B9|TvU}vw@?WQ&ybPXK^sk?eoTCW~?DzyPV+G_|R1csW|hZ##+sCI-i zKdVJ0uWJHnWuV6$c1?pNK|o53gd5Da@o zYj7;$DpmE~{(GvwKK;cd$w}Y7Q7h?jcYmuY41p#Z@fwj;lGI4AX*BFB*7ffY=`|B( sd%8K Date: Fri, 17 Jan 2020 12:38:34 +0300 Subject: [PATCH 2/3] docs: Add documentation on public keys field in session token --- docs/session.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/session.md b/docs/session.md index e8633d3..ba615c3 100644 --- a/docs/session.md +++ b/docs/session.md @@ -115,6 +115,7 @@ User token granting rights for object manipulation | ObjectID | [bytes](#bytes) | repeated | ObjectID is an object identifier of manipulation object | | Signature | [bytes](#bytes) | | Signature is a token signature, signed by owner of manipulation object | | ID | [bytes](#bytes) | | ID is a token identifier. valid UUIDv4 represented in bytes | +| PublicKeys | [bytes](#bytes) | repeated | PublicKeys associated with owner | From b556d54f16acd1de144379329a49c1c1e1570623 Mon Sep 17 00:00:00 2001 From: alexvanin Date: Fri, 17 Jan 2020 12:39:00 +0300 Subject: [PATCH 3/3] session: Modify verify routine to check owner id connection with public keys --- session/store_test.go | 6 ++++-- session/types.go | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/session/store_test.go b/session/store_test.go index 1a9e977..66f99d4 100644 --- a/session/store_test.go +++ b/session/store_test.go @@ -31,20 +31,22 @@ func newTestClient(t *testing.T) *testClient { func signToken(t *testing.T, token *PToken, c *testClient) { require.NotNil(t, token) + token.SetPublicKeys(&c.PublicKey) signH, err := c.Sign(token.Header.PublicKey) require.NoError(t, err) require.NotNil(t, signH) // data is not yet signed - require.False(t, token.Verify(&c.PublicKey)) + keys := UnmarshalPublicKeys(&token.Token) + require.False(t, token.Verify(keys...)) signT, err := c.Sign(token.verificationData()) require.NoError(t, err) require.NotNil(t, signT) token.AddSignatures(signH, signT) - require.True(t, token.Verify(&c.PublicKey)) + require.True(t, token.Verify(keys...)) } func TestTokenStore(t *testing.T) { diff --git a/session/types.go b/session/types.go index aff7cca..08abec8 100644 --- a/session/types.go +++ b/session/types.go @@ -6,6 +6,7 @@ import ( "sync" crypto "github.com/nspcc-dev/neofs-crypto" + "github.com/nspcc-dev/neofs-proto/chain" "github.com/nspcc-dev/neofs-proto/internal" "github.com/nspcc-dev/neofs-proto/refs" "github.com/pkg/errors" @@ -111,11 +112,24 @@ func (m *Token) Sign(key *ecdsa.PrivateKey) error { return nil } +// SetPublicKeys sets owner's public keys to the token +func (m *Token) SetPublicKeys(keys... *ecdsa.PublicKey) { + m.PublicKeys = m.PublicKeys[:0] + for i := range keys { + m.PublicKeys = append(m.PublicKeys, crypto.MarshalPublicKey(keys[i])) + } +} + // Verify checks if token is correct and signed. func (m *Token) Verify(keys ...*ecdsa.PublicKey) bool { if m.FirstEpoch > m.LastEpoch { return false } + ownerFromKeys := chain.KeysToAddress(keys...) + if m.OwnerID.String() != ownerFromKeys { + return false + } + for i := range keys { if m.Header.Verify(keys[i]) && crypto.Verify(keys[i], m.verificationData(), m.Signature) == nil { return true @@ -156,3 +170,12 @@ func (m *VerificationHeader) Verify(keys ...*ecdsa.PublicKey) bool { } return false } + +// UnmarshalPublicKeys returns unmarshal public keys from the token +func UnmarshalPublicKeys(t *Token) []*ecdsa.PublicKey { + r := make([]*ecdsa.PublicKey, 0, len(t.PublicKeys)) + for i := range t.PublicKeys { + r = append(r, crypto.UnmarshalPublicKey(t.PublicKeys[i])) + } + return r +}