[#78] container: Do not check signature in contract

Signature check may fail if container has NFT attributes.
So these checks should be done in alphabet nodes and not
inside the contract.

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2021-05-11 17:48:25 +03:00 committed by Alex Vanin
parent 3e70c37c22
commit ccafbcbdcd

View file

@ -127,16 +127,7 @@ func Put(container []byte, signature interop.Signature, publicKey interop.Public
} }
if !alphabetCall { if !alphabetCall {
if !isSignedByOwnerKey(container, signature, ownerID, publicKey) {
// check keys from NeoFSID
keys := contract.Call(neofsIDContractAddr, "key", contract.ReadOnly, ownerID).([]interop.PublicKey)
if !verifySignature(container, signature, keys) {
panic("put: invalid owner signature")
}
}
runtime.Notify("containerPut", container, signature, publicKey) runtime.Notify("containerPut", container, signature, publicKey)
return true return true
} }
@ -209,14 +200,6 @@ func Delete(containerID, signature []byte) bool {
} }
if !alphabetCall { if !alphabetCall {
// check provided key
neofsIDContractAddr := storage.Get(ctx, neofsIDContractKey).(interop.Hash160)
keys := contract.Call(neofsIDContractAddr, "key", contract.ReadOnly, ownerID).([]interop.PublicKey)
if !verifySignature(containerID, signature, keys) {
panic("delete: invalid owner signature")
}
runtime.Notify("containerDelete", containerID, signature) runtime.Notify("containerDelete", containerID, signature)
return true return true
} }
@ -342,30 +325,10 @@ func EACL(containerID []byte) extendedACL {
ownerID := getOwnerByID(ctx, containerID) ownerID := getOwnerByID(ctx, containerID)
if len(ownerID) == 0 { if len(ownerID) == 0 {
panic("getEACL: container does not exists") panic("eACL: container does not exists")
} }
eacl := getEACL(ctx, containerID) return 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).(interop.Hash160)
keys := contract.Call(neofsIDContractAddr, "key", contract.ReadOnly, ownerID).([]interop.PublicKey)
for i := range keys {
key := keys[i]
if crypto.VerifyWithECDsa(eacl.val, key, eacl.sig, crypto.Secp256r1) {
eacl.pub = key
break
}
}
return eacl
} }
func PutContainerSize(epoch int, cid []byte, usedSize int, pubKey interop.PublicKey) bool { func PutContainerSize(epoch int, cid []byte, usedSize int, pubKey interop.PublicKey) bool {
@ -618,17 +581,6 @@ func getEACL(ctx storage.Context, cid []byte) extendedACL {
return extendedACL{val: []byte{}, sig: interop.Signature{}, pub: interop.PublicKey{}} return extendedACL{val: []byte{}, sig: interop.Signature{}, pub: interop.PublicKey{}}
} }
func verifySignature(msg []byte, sig interop.Signature, keys []interop.PublicKey) bool {
for i := range keys {
key := keys[i]
if crypto.VerifyWithECDsa(msg, key, sig, crypto.Secp256r1) {
return true
}
}
return false
}
func getOwnerByID(ctx storage.Context, id []byte) []byte { func getOwnerByID(ctx storage.Context, id []byte) []byte {
owners := common.GetList(ctx, ownersKey) owners := common.GetList(ctx, ownersKey)
for i := 0; i < len(owners); i++ { for i := 0; i < len(owners); i++ {
@ -646,21 +598,6 @@ func getOwnerByID(ctx storage.Context, id []byte) []byte {
return nil return nil
} }
func isSignedByOwnerKey(msg []byte, sig interop.Signature, owner []byte, key interop.PublicKey) bool {
if !isOwnerFromKey(owner, key) {
return false
}
return crypto.VerifyWithECDsa(msg, key, sig, crypto.Secp256r1)
}
func isOwnerFromKey(owner []byte, key interop.PublicKey) bool {
ownerSH := common.WalletToScriptHash(owner)
keySH := contract.CreateStandardAccount(key)
return common.BytesEqual(ownerSH, keySH)
}
func estimationKey(epoch int, cid []byte) []byte { func estimationKey(epoch int, cid []byte) []byte {
var buf interface{} = epoch var buf interface{} = epoch