From 8d7e5ce20a56293da65a0b447a17153a890dcc51 Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Thu, 14 Jan 2021 18:33:50 +0300 Subject: [PATCH] [#35] container: Return public key along with eACL signature Container contract checks signature of eACL iterating through keys from neofsid contract. Clients often ask eACL from storage nodes, but it's kinda hard for them to check signature since they have no direct access to neofsid contract. So the container contract can make one more iteration through keys from neofsid contract and return suitable one. Signed-off-by: Alex Vanin --- container/container_contract.go | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/container/container_contract.go b/container/container_contract.go index 42cc0d4..df676b4 100644 --- a/container/container_contract.go +++ b/container/container_contract.go @@ -1,6 +1,7 @@ package containercontract import ( + "github.com/nspcc-dev/neo-go/pkg/interop" "github.com/nspcc-dev/neo-go/pkg/interop/binary" "github.com/nspcc-dev/neo-go/pkg/interop/blockchain" "github.com/nspcc-dev/neo-go/pkg/interop/contract" @@ -25,6 +26,7 @@ type ( extendedACL struct { val []byte sig []byte + pub interop.PublicKey } ) @@ -247,7 +249,32 @@ func SetEACL(eACL, signature []byte) bool { } func EACL(containerID []byte) extendedACL { - return getEACL(ctx, containerID) + ownerID := getOwnerByID(ctx, containerID) + if len(ownerID) == 0 { + panic("getEACL: container does not exists") + } + + eacl := getEACL(ctx, containerID) + + if len(eacl.sig) == 0 { + return eacl + } + + // attach corresponding public key if it was not revoked from neofs id + + neofsIDContractAddr := storage.Get(ctx, neofsIDContractKey).([]byte) + keys := contract.Call(neofsIDContractAddr, "key", ownerID).([][]byte) + + for i := range keys { + key := keys[i] + if crypto.ECDsaSecp256r1Verify(eacl.val, key, eacl.sig) { + eacl.pub = key + + break + } + } + + return eacl } func Version() int { @@ -421,7 +448,7 @@ func getEACL(ctx storage.Context, cid []byte) extendedACL { return binary.Deserialize(data.([]byte)).(extendedACL) } - return extendedACL{val: []byte{}, sig: []byte{}} + return extendedACL{val: []byte{}, sig: []byte{}, pub: []byte{}} } func setSerialized(ctx storage.Context, key, value interface{}) {