Add receipt check
This commit is contained in:
parent
8a414929b0
commit
0e00cf4ebb
44
commonspace/checks.go
Normal file
44
commonspace/checks.go
Normal 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
|
||||||
|
}
|
||||||
85
coordinator/coordinatorclient/receipt.go
Normal file
85
coordinator/coordinatorclient/receipt.go
Normal 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
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user