Add receipt check

This commit is contained in:
mcrakhman 2023-04-24 20:33:35 +02:00 committed by Mikhail Iudin
parent 8a414929b0
commit 0e00cf4ebb
No known key found for this signature in database
GPG Key ID: FAAAA8BAABDFF1C0
2 changed files with 129 additions and 0 deletions

44
commonspace/checks.go Normal file
View File

@ -0,0 +1,44 @@
package commonspace
import (
"context"
"github.com/anytypeio/any-sync/commonspace/spacesyncproto"
"github.com/anytypeio/any-sync/net/peer"
"github.com/anytypeio/any-sync/nodeconf"
"github.com/anytypeio/any-sync/util/crypto"
"golang.org/x/exp/slices"
)
func CheckResponsible(ctx context.Context, confService nodeconf.Service, spaceId string) (err error) {
peerId, err := peer.CtxPeerId(ctx)
if err != nil {
return
}
if isClient(confService, peerId) && !confService.IsResponsible(spaceId) {
return spacesyncproto.ErrPeerIsNotResponsible
}
return
}
func isClient(confService nodeconf.Service, peerId string) bool {
return len(confService.NodeTypes(peerId)) == 0
}
func checkCoordinator(confService nodeconf.Service, identity []byte, payload, signature []byte) (err error) {
controlKey, err := crypto.UnmarshalEd25519PublicKey(identity)
if err != nil {
return
}
nodeTypes := confService.NodeTypes(controlKey.PeerId())
if len(nodeTypes) == 0 || !slices.Contains(nodeTypes, nodeconf.NodeTypeCoordinator) {
return errNoSuchCoordinatorNode
}
res, err := controlKey.Verify(payload, signature)
if err != nil {
return
}
if !res {
return errReceiptSignatureIncorrect
}
return
}

View File

@ -0,0 +1,85 @@
package coordinatorclient
import (
"bytes"
"context"
"errors"
"github.com/anytypeio/any-sync/commonspace/spacesyncproto"
"github.com/anytypeio/any-sync/coordinator/coordinatorproto"
"github.com/anytypeio/any-sync/net/peer"
"github.com/anytypeio/any-sync/nodeconf"
"github.com/anytypeio/any-sync/util/crypto"
"github.com/gogo/protobuf/proto"
"golang.org/x/exp/slices"
"time"
)
var (
errReceiptSignatureIncorrect = errors.New("receipt signature is incorrect")
errNoSuchCoordinatorNode = errors.New("no such control node")
errReceiptSpaceIdIncorrect = errors.New("receipt space id is incorrect")
errReceiptPeerIdIncorrect = errors.New("receipt peer id is incorrect")
errReceiptAccountIncorrect = errors.New("receipt account id is incorrect")
errReceiptExpired = errors.New("receipt is expired")
)
func CheckReceipt(ctx context.Context, confService nodeconf.Service, request *spacesyncproto.SpacePushRequest) (err error) {
peerId, err := peer.CtxPeerId(ctx)
if err != nil {
return
}
accountIdentity, err := peer.CtxIdentity(ctx)
if err != nil {
return
}
credential := &coordinatorproto.SpaceReceiptWithSignature{}
err = proto.Unmarshal(request.GetCredential(), credential)
if err != nil {
return
}
payload := &coordinatorproto.SpaceReceipt{}
err = proto.Unmarshal(credential.GetSpaceReceiptPayload(), payload)
if err != nil {
return
}
if payload.GetSpaceId() != request.GetPayload().GetSpaceHeader().GetId() {
return errReceiptSpaceIdIncorrect
}
if payload.GetPeerId() != peerId {
return errReceiptPeerIdIncorrect
}
if !bytes.Equal(payload.GetAccountIdentity(), accountIdentity) {
return errReceiptAccountIncorrect
}
err = checkCoordinator(
confService,
payload.GetControlNodeIdentity(),
credential.GetSpaceReceiptPayload(),
credential.GetSignature())
if err != nil {
return
}
if payload.GetValidUntil() < uint64(time.Now().Unix()) {
return errReceiptExpired
}
return
}
func checkCoordinator(confService nodeconf.Service, identity []byte, payload, signature []byte) (err error) {
cooordinatorKey, err := crypto.UnmarshalEd25519PublicKey(identity)
if err != nil {
return
}
nodeTypes := confService.NodeTypes(cooordinatorKey.PeerId())
if len(nodeTypes) == 0 || !slices.Contains(nodeTypes, nodeconf.NodeTypeCoordinator) {
return errNoSuchCoordinatorNode
}
res, err := cooordinatorKey.Verify(payload, signature)
if err != nil {
return
}
if !res {
return errReceiptSignatureIncorrect
}
return
}