Merge pull request #181 from keep-network/test-adversarial-signing

Test adversarial signing
This commit is contained in:
vyzo 2019-05-08 20:27:41 +03:00 committed by GitHub
commit 9d7a59f4a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 127 additions and 8 deletions

View File

@ -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,
)
}
}