2021-11-18 13:21:36 +00:00
|
|
|
package rpc
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/ecdsa"
|
|
|
|
"crypto/rand"
|
|
|
|
"encoding/hex"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
2021-12-09 09:07:08 +00:00
|
|
|
"sync"
|
2021-11-18 13:21:36 +00:00
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
|
|
"github.com/status-im/go-waku/waku/v2/node"
|
2021-12-08 08:52:27 +00:00
|
|
|
"github.com/status-im/go-waku/waku/v2/protocol/pb"
|
2021-11-18 13:21:36 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type PrivateService struct {
|
|
|
|
node *node.WakuNode
|
2021-12-09 09:07:08 +00:00
|
|
|
|
|
|
|
symmetricMessages map[string][]*pb.WakuMessage
|
|
|
|
symmetricMessagesMutex sync.RWMutex
|
|
|
|
|
|
|
|
asymmetricMessages map[string][]*pb.WakuMessage
|
|
|
|
asymmetricMessagesMutex sync.RWMutex
|
2021-11-18 13:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type SymmetricKeyReply struct {
|
|
|
|
Key string `json:"key"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type KeyPairReply struct {
|
|
|
|
PrivateKey string `json:"privateKey"`
|
|
|
|
PulicKey string `json:"publicKey"`
|
|
|
|
}
|
|
|
|
|
2021-12-08 08:52:27 +00:00
|
|
|
type SymmetricMessageArgs struct {
|
|
|
|
Topic string `json:"topic"`
|
|
|
|
Message pb.WakuMessage `json:"message"`
|
|
|
|
SymKey string `json:"symkey"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type AsymmetricMessageArgs struct {
|
|
|
|
Topic string `json:"topic"`
|
|
|
|
Message pb.WakuMessage `json:"message"`
|
|
|
|
PublicKey string `json:"publicKey"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type SymmetricMessagesArgs struct {
|
|
|
|
Topic string `json:"topic"`
|
|
|
|
SymKey string `json:"symkey"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type AsymmetricMessagesArgs struct {
|
|
|
|
Topic string `json:"topic"`
|
|
|
|
PrivateKey string `json:"privateKey"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewPrivateService(node *node.WakuNode) *PrivateService {
|
|
|
|
return &PrivateService{
|
2021-12-09 09:07:08 +00:00
|
|
|
node: node,
|
|
|
|
symmetricMessages: make(map[string][]*pb.WakuMessage),
|
|
|
|
asymmetricMessages: make(map[string][]*pb.WakuMessage),
|
2021-12-08 08:52:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-18 13:21:36 +00:00
|
|
|
func (p *PrivateService) GetV1SymmetricKey(req *http.Request, args *Empty, reply *SymmetricKeyReply) error {
|
|
|
|
key := [32]byte{}
|
|
|
|
_, err := rand.Read(key[:])
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
reply.Key = hex.EncodeToString(key[:])
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *PrivateService) GetV1AsymmetricKeypair(req *http.Request, args *Empty, reply *KeyPairReply) error {
|
|
|
|
privateKey, err := crypto.GenerateKey()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
privateKeyBytes := crypto.FromECDSA(privateKey)
|
|
|
|
|
|
|
|
publicKey := privateKey.Public()
|
|
|
|
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
|
|
|
|
if !ok {
|
|
|
|
return fmt.Errorf("cannot assert type: publicKey is not of type *ecdsa.PublicKey")
|
|
|
|
}
|
|
|
|
|
|
|
|
publicKeyBytes := crypto.FromECDSAPub(publicKeyECDSA)
|
|
|
|
reply.PrivateKey = hex.EncodeToString(privateKeyBytes[:])
|
|
|
|
reply.PulicKey = hex.EncodeToString(publicKeyBytes[:])
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-12-08 08:52:27 +00:00
|
|
|
func (p *PrivateService) PostV1SymmetricMessage(req *http.Request, args *SymmetricMessageArgs, reply *SuccessReply) error {
|
|
|
|
keyInfo := new(node.KeyInfo)
|
|
|
|
keyInfo.Kind = node.Symmetric
|
|
|
|
keyInfo.SymKey = []byte(args.SymKey)
|
|
|
|
|
|
|
|
err := node.EncodeWakuMessage(&args.Message, keyInfo)
|
|
|
|
if err != nil {
|
|
|
|
reply.Error = err.Error()
|
|
|
|
reply.Success = false
|
2021-12-09 09:07:08 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
err = p.node.Publish(req.Context(), &args.Message)
|
|
|
|
if err != nil {
|
|
|
|
reply.Error = err.Error()
|
|
|
|
reply.Success = false
|
|
|
|
return nil
|
2021-12-08 08:52:27 +00:00
|
|
|
}
|
|
|
|
|
2021-12-09 09:07:08 +00:00
|
|
|
p.symmetricMessagesMutex.Lock()
|
|
|
|
defer p.symmetricMessagesMutex.Unlock()
|
|
|
|
if _, ok := p.symmetricMessages[args.Topic]; !ok {
|
|
|
|
p.symmetricMessages[args.Topic] = make([]*pb.WakuMessage, 0)
|
|
|
|
}
|
|
|
|
p.symmetricMessages[args.Topic] = append(p.symmetricMessages[args.Topic], &args.Message)
|
|
|
|
|
|
|
|
reply.Success = true
|
2021-12-08 08:52:27 +00:00
|
|
|
return nil
|
2021-11-18 13:21:36 +00:00
|
|
|
}
|
|
|
|
|
2021-12-08 08:52:27 +00:00
|
|
|
func (p *PrivateService) PostV1AsymmetricMessage(req *http.Request, args *AsymmetricMessageArgs, reply *SuccessReply) error {
|
|
|
|
keyInfo := new(node.KeyInfo)
|
|
|
|
keyInfo.Kind = node.Asymmetric
|
|
|
|
pubKeyBytes, err := hex.DecodeString(args.PublicKey)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("public key cannot be decoded: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
pubKey, err := crypto.UnmarshalPubkey(pubKeyBytes)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("public key cannot be unmarshalled: %v", err)
|
|
|
|
}
|
|
|
|
keyInfo.PubKey = *pubKey
|
|
|
|
|
|
|
|
err = node.EncodeWakuMessage(&args.Message, keyInfo)
|
|
|
|
if err != nil {
|
|
|
|
reply.Error = err.Error()
|
|
|
|
reply.Success = false
|
2021-12-09 09:07:08 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
err = p.node.Publish(req.Context(), &args.Message)
|
|
|
|
if err != nil {
|
|
|
|
reply.Error = err.Error()
|
|
|
|
reply.Success = false
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
p.asymmetricMessagesMutex.Lock()
|
|
|
|
defer p.asymmetricMessagesMutex.Unlock()
|
|
|
|
if _, ok := p.asymmetricMessages[args.Topic]; !ok {
|
|
|
|
p.asymmetricMessages[args.Topic] = make([]*pb.WakuMessage, 0)
|
2021-12-08 08:52:27 +00:00
|
|
|
}
|
2021-12-09 09:07:08 +00:00
|
|
|
p.asymmetricMessages[args.Topic] = append(p.asymmetricMessages[args.Topic], &args.Message)
|
2021-12-08 08:52:27 +00:00
|
|
|
|
2021-12-09 09:07:08 +00:00
|
|
|
reply.Success = true
|
2021-12-08 08:52:27 +00:00
|
|
|
return nil
|
2021-11-18 13:21:36 +00:00
|
|
|
}
|
|
|
|
|
2021-12-08 08:52:27 +00:00
|
|
|
func (p *PrivateService) GetV1SymmetricMessages(req *http.Request, args *SymmetricMessagesArgs, reply *MessagesReply) error {
|
2021-12-09 09:07:08 +00:00
|
|
|
p.symmetricMessagesMutex.Lock()
|
|
|
|
defer p.symmetricMessagesMutex.Unlock()
|
|
|
|
|
|
|
|
if _, ok := p.symmetricMessages[args.Topic]; !ok {
|
|
|
|
return fmt.Errorf("topic %s not subscribed", args.Topic)
|
|
|
|
}
|
|
|
|
|
|
|
|
reply.Messages = p.symmetricMessages[args.Topic]
|
|
|
|
p.symmetricMessages[args.Topic] = make([]*pb.WakuMessage, 0)
|
|
|
|
return nil
|
2021-11-18 13:21:36 +00:00
|
|
|
}
|
|
|
|
|
2021-12-08 08:52:27 +00:00
|
|
|
func (p *PrivateService) GetV1AsymmetricMessages(req *http.Request, args *AsymmetricMessagesArgs, reply *MessagesReply) error {
|
2021-12-09 09:07:08 +00:00
|
|
|
p.asymmetricMessagesMutex.Lock()
|
|
|
|
defer p.asymmetricMessagesMutex.Unlock()
|
|
|
|
|
|
|
|
if _, ok := p.asymmetricMessages[args.Topic]; !ok {
|
|
|
|
return fmt.Errorf("topic %s not subscribed", args.Topic)
|
|
|
|
}
|
|
|
|
|
|
|
|
reply.Messages = p.asymmetricMessages[args.Topic]
|
|
|
|
p.asymmetricMessages[args.Topic] = make([]*pb.WakuMessage, 0)
|
|
|
|
return nil
|
2021-11-18 13:21:36 +00:00
|
|
|
}
|