Merge pull request #181 from keep-network/test-adversarial-signing
Test adversarial signing
This commit is contained in:
commit
9d7a59f4a8
135
floodsub_test.go
135
floodsub_test.go
|
@ -10,12 +10,11 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
bhost "github.com/libp2p/go-libp2p-blankhost"
|
||||||
host "github.com/libp2p/go-libp2p-host"
|
host "github.com/libp2p/go-libp2p-host"
|
||||||
peer "github.com/libp2p/go-libp2p-peer"
|
peer "github.com/libp2p/go-libp2p-peer"
|
||||||
|
protocol "github.com/libp2p/go-libp2p-protocol"
|
||||||
swarmt "github.com/libp2p/go-libp2p-swarm/testing"
|
swarmt "github.com/libp2p/go-libp2p-swarm/testing"
|
||||||
//bhost "github.com/libp2p/go-libp2p/p2p/host/basic"
|
|
||||||
bhost "github.com/libp2p/go-libp2p-blankhost"
|
|
||||||
"github.com/libp2p/go-libp2p-protocol"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkMessageRouting(t *testing.T, topic string, pubs []*PubSub, subs []*Subscription) {
|
func checkMessageRouting(t *testing.T, topic string, pubs []*PubSub, subs []*Subscription) {
|
||||||
|
@ -90,14 +89,18 @@ func connectAll(t *testing.T, hosts []host.Host) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getPubsub(ctx context.Context, h host.Host, opts ...Option) *PubSub {
|
||||||
|
ps, err := NewFloodSub(ctx, h, opts...)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return ps
|
||||||
|
}
|
||||||
|
|
||||||
func getPubsubs(ctx context.Context, hs []host.Host, opts ...Option) []*PubSub {
|
func getPubsubs(ctx context.Context, hs []host.Host, opts ...Option) []*PubSub {
|
||||||
var psubs []*PubSub
|
var psubs []*PubSub
|
||||||
for _, h := range hs {
|
for _, h := range hs {
|
||||||
ps, err := NewFloodSub(ctx, h, opts...)
|
psubs = append(psubs, getPubsub(ctx, h, opts...))
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
psubs = append(psubs, ps)
|
|
||||||
}
|
}
|
||||||
return psubs
|
return psubs
|
||||||
}
|
}
|
||||||
|
@ -943,3 +946,119 @@ func TestWithSigning(t *testing.T) {
|
||||||
t.Fatalf("unexpected data: %s", string(msg.Data))
|
t.Fatalf("unexpected data: %s", string(msg.Data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestImproperlySignedMessageRejected(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
hosts := getNetHosts(t, ctx, 2)
|
||||||
|
adversary := hosts[0]
|
||||||
|
honestPeer := hosts[1]
|
||||||
|
|
||||||
|
// The adversary enables signing, but disables verification to let through
|
||||||
|
// an incorrectly signed message.
|
||||||
|
adversaryPubSub := getPubsub(
|
||||||
|
ctx,
|
||||||
|
adversary,
|
||||||
|
WithMessageSigning(true),
|
||||||
|
WithStrictSignatureVerification(false),
|
||||||
|
)
|
||||||
|
honestPubSub := getPubsub(
|
||||||
|
ctx,
|
||||||
|
honestPeer,
|
||||||
|
WithStrictSignatureVerification(true),
|
||||||
|
)
|
||||||
|
|
||||||
|
connect(t, adversary, honestPeer)
|
||||||
|
|
||||||
|
var (
|
||||||
|
topic = "foobar"
|
||||||
|
correctMessage = []byte("this is a correct message")
|
||||||
|
incorrectMessage = []byte("this is the incorrect message")
|
||||||
|
)
|
||||||
|
|
||||||
|
adversarySubscription, err := adversaryPubSub.Subscribe(topic)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
honestPeerSubscription, err := honestPubSub.Subscribe(topic)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
time.Sleep(time.Millisecond * 50)
|
||||||
|
|
||||||
|
// First the adversary sends the correct message.
|
||||||
|
err = adversaryPubSub.Publish(topic, correctMessage)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change the sign key for the adversarial peer, and send the second,
|
||||||
|
// incorrectly signed, message.
|
||||||
|
adversaryPubSub.signID = honestPubSub.signID
|
||||||
|
adversaryPubSub.signKey = honestPubSub.host.Peerstore().PrivKey(honestPubSub.signID)
|
||||||
|
err = adversaryPubSub.Publish(topic, incorrectMessage)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var adversaryMessages []*Message
|
||||||
|
adversaryContext, adversaryCancel := context.WithCancel(ctx)
|
||||||
|
go func(ctx context.Context) {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
msg, err := adversarySubscription.Next(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
adversaryMessages = append(adversaryMessages, msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}(adversaryContext)
|
||||||
|
|
||||||
|
<-time.After(1 * time.Second)
|
||||||
|
adversaryCancel()
|
||||||
|
|
||||||
|
// Ensure the adversary successfully publishes the incorrectly signed
|
||||||
|
// message. If the adversary "sees" this, we successfully got through
|
||||||
|
// their local validation.
|
||||||
|
if len(adversaryMessages) != 2 {
|
||||||
|
t.Fatalf("got %d messages, expected 2", len(adversaryMessages))
|
||||||
|
}
|
||||||
|
|
||||||
|
// the honest peer's validation process will drop the message;
|
||||||
|
// next will never furnish the incorrect message.
|
||||||
|
var honestPeerMessages []*Message
|
||||||
|
honestPeerContext, honestPeerCancel := context.WithCancel(ctx)
|
||||||
|
go func(ctx context.Context) {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
msg, err := honestPeerSubscription.Next(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
honestPeerMessages = append(honestPeerMessages, msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}(honestPeerContext)
|
||||||
|
|
||||||
|
<-time.After(1 * time.Second)
|
||||||
|
honestPeerCancel()
|
||||||
|
|
||||||
|
if len(honestPeerMessages) != 1 {
|
||||||
|
t.Fatalf("got %d messages, expected 1", len(honestPeerMessages))
|
||||||
|
}
|
||||||
|
if string(honestPeerMessages[0].GetData()) != string(correctMessage) {
|
||||||
|
t.Fatalf(
|
||||||
|
"got %s, expected message %s",
|
||||||
|
honestPeerMessages[0].GetData(),
|
||||||
|
correctMessage,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue