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"
|
||||
"time"
|
||||
|
||||
bhost "github.com/libp2p/go-libp2p-blankhost"
|
||||
host "github.com/libp2p/go-libp2p-host"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
protocol "github.com/libp2p/go-libp2p-protocol"
|
||||
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) {
|
||||
|
@ -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 {
|
||||
var psubs []*PubSub
|
||||
for _, h := range hs {
|
||||
ps, err := NewFloodSub(ctx, h, opts...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
psubs = append(psubs, ps)
|
||||
psubs = append(psubs, getPubsub(ctx, h, opts...))
|
||||
}
|
||||
return psubs
|
||||
}
|
||||
|
@ -943,3 +946,119 @@ func TestWithSigning(t *testing.T) {
|
|||
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