mirror of
https://github.com/logos-messaging/logos-messaging-go.git
synced 2026-01-04 06:53:06 +00:00
chore: add unit test for signed validator and --protected-topic-flag
This commit is contained in:
parent
f2d2e8127a
commit
837a0f2708
@ -206,6 +206,14 @@ var (
|
|||||||
Destination: &options.Relay.Topics,
|
Destination: &options.Relay.Topics,
|
||||||
EnvVars: []string{"WAKUNODE2_TOPICS"},
|
EnvVars: []string{"WAKUNODE2_TOPICS"},
|
||||||
})
|
})
|
||||||
|
ProtectedTopics = cliutils.NewGenericFlagMultiValue(&cli.GenericFlag{
|
||||||
|
Name: "protected-topic",
|
||||||
|
Usage: "Topics and its public key to be used for message validation, topic:pubkey. Argument may be repeated.",
|
||||||
|
EnvVars: []string{"WAKUNODE2_PROTECTED_TOPIC"},
|
||||||
|
Value: &cliutils.ProtectedTopicSlice{
|
||||||
|
Values: &options.Relay.ProtectedTopics,
|
||||||
|
},
|
||||||
|
})
|
||||||
RelayPeerExchange = altsrc.NewBoolFlag(&cli.BoolFlag{
|
RelayPeerExchange = altsrc.NewBoolFlag(&cli.BoolFlag{
|
||||||
Name: "relay-peer-exchange",
|
Name: "relay-peer-exchange",
|
||||||
Value: false,
|
Value: false,
|
||||||
|
|||||||
@ -45,6 +45,7 @@ func main() {
|
|||||||
AgentString,
|
AgentString,
|
||||||
Relay,
|
Relay,
|
||||||
Topics,
|
Topics,
|
||||||
|
ProtectedTopics,
|
||||||
RelayPeerExchange,
|
RelayPeerExchange,
|
||||||
MinRelayPeersToPublish,
|
MinRelayPeersToPublish,
|
||||||
StoreNodeFlag,
|
StoreNodeFlag,
|
||||||
|
|||||||
55
waku/cliutils/protected_topic.go
Normal file
55
waku/cliutils/protected_topic.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package cliutils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProtectedTopic struct {
|
||||||
|
Topic string
|
||||||
|
PublicKey *ecdsa.PublicKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p ProtectedTopic) String() string {
|
||||||
|
pubKBytes := crypto.FromECDSAPub(p.PublicKey)
|
||||||
|
return fmt.Sprintf("%s:%s", p.Topic, hex.EncodeToString(pubKBytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProtectedTopicSlice struct {
|
||||||
|
Values *[]ProtectedTopic
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k *ProtectedTopicSlice) Set(value string) error {
|
||||||
|
protectedTopicParts := strings.Split(value, ":")
|
||||||
|
if len(protectedTopicParts) != 2 {
|
||||||
|
return errors.New("expected topic_name:hex_encoded_public_key")
|
||||||
|
}
|
||||||
|
|
||||||
|
pubk, err := crypto.UnmarshalPubkey(common.FromHex(protectedTopicParts[1]))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*k.Values = append(*k.Values, ProtectedTopic{
|
||||||
|
Topic: protectedTopicParts[0],
|
||||||
|
PublicKey: pubk,
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *ProtectedTopicSlice) String() string {
|
||||||
|
if v.Values == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
var output []string
|
||||||
|
for _, v := range *v.Values {
|
||||||
|
output = append(output, v.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(output, ", ")
|
||||||
|
}
|
||||||
@ -300,6 +300,11 @@ func Execute(options Options) {
|
|||||||
failOnErr(err, "Error subscring to topic")
|
failOnErr(err, "Error subscring to topic")
|
||||||
wakuNode.Broadcaster().Unregister(&nodeTopic, sub.C)
|
wakuNode.Broadcaster().Unregister(&nodeTopic, sub.C)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, protectedTopic := range options.Relay.ProtectedTopics {
|
||||||
|
err := wakuNode.Relay().AddSignedTopicValidator(protectedTopic.Topic, protectedTopic.PublicKey)
|
||||||
|
failOnErr(err, "Error adding signed topic validator")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, n := range options.StaticNodes {
|
for _, n := range options.StaticNodes {
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/multiformats/go-multiaddr"
|
"github.com/multiformats/go-multiaddr"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
|
"github.com/waku-org/go-waku/waku/cliutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DiscV5Options are settings to enable a modified version of Ethereum’s Node
|
// DiscV5Options are settings to enable a modified version of Ethereum’s Node
|
||||||
@ -24,6 +25,7 @@ type DiscV5Options struct {
|
|||||||
type RelayOptions struct {
|
type RelayOptions struct {
|
||||||
Enable bool
|
Enable bool
|
||||||
Topics cli.StringSlice
|
Topics cli.StringSlice
|
||||||
|
ProtectedTopics []cliutils.ProtectedTopic
|
||||||
PeerExchange bool
|
PeerExchange bool
|
||||||
MinRelayPeersToPublish int
|
MinRelayPeersToPublish int
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,9 +21,10 @@ func MsgHash(pubSubTopic string, msg *pb.WakuMessage) []byte {
|
|||||||
return hash.SHA256([]byte(pubSubTopic), msg.Payload, []byte(msg.ContentTopic))
|
return hash.SHA256([]byte(pubSubTopic), msg.Payload, []byte(msg.ContentTopic))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WakuRelay) AddSignedTopicValidator(topic string, publicKey *ecdsa.PublicKey) error {
|
type validatorFn = func(ctx context.Context, peerID peer.ID, message *pubsub.Message) bool
|
||||||
w.log.Info("adding validator to signed topic", zap.String("topic", topic), zap.String("publicKey", hex.EncodeToString(elliptic.Marshal(publicKey.Curve, publicKey.X, publicKey.Y))))
|
|
||||||
err := w.pubsub.RegisterTopicValidator(topic, func(ctx context.Context, peerID peer.ID, message *pubsub.Message) bool {
|
func validatorFnBuilder(topic string, publicKey *ecdsa.PublicKey) validatorFn {
|
||||||
|
return func(ctx context.Context, peerID peer.ID, message *pubsub.Message) bool {
|
||||||
msg := new(pb.WakuMessage)
|
msg := new(pb.WakuMessage)
|
||||||
err := proto.Unmarshal(message.Data, msg)
|
err := proto.Unmarshal(message.Data, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -34,11 +35,16 @@ func (w *WakuRelay) AddSignedTopicValidator(topic string, publicKey *ecdsa.Publi
|
|||||||
signature := msg.Meta
|
signature := msg.Meta
|
||||||
|
|
||||||
return ecdsa.VerifyASN1(publicKey, msgHash, signature)
|
return ecdsa.VerifyASN1(publicKey, msgHash, signature)
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WakuRelay) AddSignedTopicValidator(topic string, publicKey *ecdsa.PublicKey) error {
|
||||||
|
w.log.Info("adding validator to signed topic", zap.String("topic", topic), zap.String("publicKey", hex.EncodeToString(elliptic.Marshal(publicKey.Curve, publicKey.X, publicKey.Y))))
|
||||||
|
err := w.pubsub.RegisterTopicValidator(topic, validatorFnBuilder(topic, publicKey))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WakuRelay) SignMessage(privKey *ecdsa.PrivateKey, topic string, msg *pb.WakuMessage) error {
|
func SignMessage(privKey *ecdsa.PrivateKey, topic string, msg *pb.WakuMessage) error {
|
||||||
msgHash := MsgHash(topic, msg)
|
msgHash := MsgHash(topic, msg)
|
||||||
sign, err := ecdsa.SignASN1(rand.Reader, privKey, msgHash)
|
sign, err := ecdsa.SignASN1(rand.Reader, privKey, msgHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
47
waku/v2/protocol/relay/validators_test.go
Normal file
47
waku/v2/protocol/relay/validators_test.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package relay
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||||
|
pubsub_pb "github.com/libp2p/go-libp2p-pubsub/pb"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/waku-org/go-waku/waku/v2/protocol/pb"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMsgHash(t *testing.T) {
|
||||||
|
privKeyB, _ := hexutil.Decode("0x5526a8990317c9b7b58d07843d270f9cd1d9aaee129294c1c478abf7261dd9e6")
|
||||||
|
prvKey, _ := crypto.ToECDSA(privKeyB)
|
||||||
|
|
||||||
|
payload, _ := hexutil.Decode("0x3af5c7a8d71498e82e1991089d8429448f3b78277fac141af9052e77fc003dfb")
|
||||||
|
contentTopic := "my-content-topic"
|
||||||
|
pubsubTopic := "some-spam-protected-topic"
|
||||||
|
|
||||||
|
msg := &pb.WakuMessage{
|
||||||
|
Payload: payload,
|
||||||
|
ContentTopic: contentTopic,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := SignMessage(prvKey, pubsubTopic, msg)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
msgData, _ := proto.Marshal(msg)
|
||||||
|
|
||||||
|
expectedMessageHash, _ := hexutil.Decode("0xd0e3231ec48f9c0cf9306b7100c30b4e85c78854b67b41e4ee388fb4610f543d")
|
||||||
|
messageHash := MsgHash(pubsubTopic, msg)
|
||||||
|
require.True(t, bytes.Equal(expectedMessageHash, messageHash))
|
||||||
|
|
||||||
|
myValidator := validatorFnBuilder(pubsubTopic, &prvKey.PublicKey)
|
||||||
|
|
||||||
|
result := myValidator(context.Background(), "", &pubsub.Message{
|
||||||
|
Message: &pubsub_pb.Message{
|
||||||
|
Data: msgData,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.True(t, result)
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user