libs5-go/protocol/signed/signed_message.go

110 lines
2.0 KiB
Go

package signed
import (
"crypto/ed25519"
"errors"
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
"git.lumeweb.com/LumeWeb/libs5-go/interfaces"
"git.lumeweb.com/LumeWeb/libs5-go/net"
"git.lumeweb.com/LumeWeb/libs5-go/protocol/base"
"git.lumeweb.com/LumeWeb/libs5-go/types"
"github.com/vmihailenco/msgpack/v5"
)
var (
_ base.IncomingMessageTyped = (*SignedMessage)(nil)
_ msgpack.CustomDecoder = (*signedMessagePayoad)(nil)
)
var (
errInvalidSignature = errors.New("Invalid signature found")
)
type SignedMessage struct {
nodeId *encoding.NodeId
signature []byte
message []byte
base.IncomingMessageTypedImpl
}
type signedMessagePayoad struct {
kind int
message msgpack.RawMessage
}
func (s *signedMessagePayoad) DecodeMsgpack(dec *msgpack.Decoder) error {
kind, err := dec.DecodeInt()
if err != nil {
return err
}
s.kind = kind
message, err := dec.DecodeRaw()
if err != nil {
return err
}
s.message = message
return nil
}
func NewSignedMessage() *SignedMessage {
return &SignedMessage{}
}
func (s *SignedMessage) HandleMessage(node interfaces.Node, peer *net.Peer, verifyId bool) error {
var payload signedMessagePayoad
err := msgpack.Unmarshal(s.message, &payload)
if err != nil {
return err
}
if msgHandler, valid := GetMessageType(types.ProtocolMethod(payload.kind)); valid {
msgHandler.SetIncomingMessage(s)
err := msgpack.Unmarshal(payload.message, &msgHandler)
if err != nil {
return err
}
err = msgHandler.HandleMessage(node, peer, verifyId)
if err != nil {
return err
}
}
return nil
}
func (s *SignedMessage) DecodeMessage(dec *msgpack.Decoder) error {
nodeId, err := dec.DecodeBytes()
if err != nil {
return err
}
s.nodeId = encoding.NewNodeId(nodeId)
signature, err := dec.DecodeBytes()
if err != nil {
return err
}
s.signature = signature
message, err := dec.DecodeBytes()
if err != nil {
return err
}
s.message = message
if !ed25519.Verify(s.nodeId.Raw(), s.message, s.signature) {
return errInvalidSignature
}
return nil
}