Skip to content
This repository has been archived by the owner on May 26, 2022. It is now read-only.

Commit

Permalink
add the peer ID to SecureInbound
Browse files Browse the repository at this point in the history
  • Loading branch information
marten-seemann committed Sep 5, 2021
1 parent 1ef22cf commit df52653
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 20 deletions.
2 changes: 1 addition & 1 deletion benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (b benchenv) connect(stopTimer bool) (*secureSession, *secureSession) {
initSession, initErr = b.initTpt.SecureOutbound(context.TODO(), initConn, b.respTpt.localID)
}()

respSession, respErr := b.respTpt.SecureInbound(context.TODO(), respConn)
respSession, respErr := b.respTpt.SecureInbound(context.TODO(), respConn, "")
<-done

if initErr != nil {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/flynn/noise v1.0.0
github.com/gogo/protobuf v1.3.2
github.com/libp2p/go-buffer-pool v0.0.2
github.com/libp2p/go-libp2p-core v0.9.0
github.com/libp2p/go-libp2p-core v0.9.1-0.20210905142029-b0e6ce9862eb
github.com/multiformats/go-multiaddr v0.3.3 // indirect
github.com/multiformats/go-multihash v0.0.15 // indirect
github.com/stretchr/testify v1.7.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs=
github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM=
github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs=
github.com/libp2p/go-libp2p-core v0.9.0 h1:t97Mv0LIBZlP2FXVRNKKVzHJCIjbIWGxYptGId4+htU=
github.com/libp2p/go-libp2p-core v0.9.0/go.mod h1:ESsbz31oC3C1AvMJoGx26RTuCkNhmkSRCqZ0kQtJ2/8=
github.com/libp2p/go-libp2p-core v0.9.1-0.20210905142029-b0e6ce9862eb h1:pjj6sLBhON3OI3gMo/LHNVzgC1uIYz5GPm8SlQTXnjg=
github.com/libp2p/go-libp2p-core v0.9.1-0.20210905142029-b0e6ce9862eb/go.mod h1:QQrJQ1IV5nm3/nEeCApfbuwlqzKDCJPRvRoS7Ob5NmQ=
github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU=
github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA=
github.com/libp2p/go-openssl v0.0.7 h1:eCAzdLejcNVBzP/iZM9vqHnQm+XyCEbSSIheIPRGNsw=
Expand Down
6 changes: 3 additions & 3 deletions handshake.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ func (s *secureSession) runHandshake(ctx context.Context) error {
}
}

// We can re-use this buffer for all handshake messages as it's size
// We can re-use this buffer for all handshake messages as its size
// will be the size of the maximum handshake message for the Noise XX pattern.
// Also, since we prefix every noise handshake message with it's length, we need to account for
// Also, since we prefix every noise handshake message with its length, we need to account for
// it when we fetch the buffer from the pool
maxMsgSize := 2*noise.DH25519.DHLen() + len(payload) + 2*poly1305.TagSize
hbuf := pool.Get(maxMsgSize + LengthPrefixLength)
Expand Down Expand Up @@ -243,7 +243,7 @@ func (s *secureSession) handleRemoteHandshakePayload(payload []byte, remoteStati
}

// if we know who we're trying to reach, make sure we have the right peer
if s.initiator && s.remoteID != id {
if s.remoteID != "" && s.remoteID != id {
// use Pretty() as it produces the full b58-encoded string, rather than abbreviated forms.
return fmt.Errorf("peer id mismatch: expected %s, but remote key matches %s", s.remoteID.Pretty(), id.Pretty())
}
Expand Down
5 changes: 3 additions & 2 deletions transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ func New(privkey crypto.PrivKey) (*Transport, error) {
}

// SecureInbound runs the Noise handshake as the responder.
func (t *Transport) SecureInbound(ctx context.Context, insecure net.Conn) (sec.SecureConn, error) {
return newSecureSession(t, ctx, insecure, "", false)
// If p is empty, connections from any peer are accepted.
func (t *Transport) SecureInbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) {
return newSecureSession(t, ctx, insecure, p, false)
}

// SecureOutbound runs the Noise handshake as the initiator.
Expand Down
67 changes: 56 additions & 11 deletions transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ import (
"context"
"encoding/binary"
"errors"
"golang.org/x/crypto/poly1305"
"io"
"math/rand"
"net"
"testing"
"time"

crypto "github.com/libp2p/go-libp2p-core/crypto"
"github.com/stretchr/testify/assert"

"golang.org/x/crypto/poly1305"

"github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/sec"

Expand Down Expand Up @@ -79,7 +82,7 @@ func connect(t *testing.T, initTransport, respTransport *Transport) (*secureSess
initConn, initErr = initTransport.SecureOutbound(context.TODO(), init, respTransport.localID)
}()

respConn, respErr := respTransport.SecureInbound(context.TODO(), resp)
respConn, respErr := respTransport.SecureInbound(context.TODO(), resp, "")
<-done

if initErr != nil {
Expand Down Expand Up @@ -161,24 +164,66 @@ func TestKeys(t *testing.T) {
}
}

func TestPeerIDMismatchFailsHandshake(t *testing.T) {
func TestPeerIDMatch(t *testing.T) {
initTransport := newTestTransport(t, crypto.Ed25519, 2048)
respTransport := newTestTransport(t, crypto.Ed25519, 2048)
init, resp := newConnPair(t)

var initErr error
done := make(chan struct{})
go func() {
defer close(done)
_, initErr = initTransport.SecureOutbound(context.TODO(), init, "a-random-peer-id")
conn, err := initTransport.SecureOutbound(context.TODO(), init, respTransport.localID)
assert.NoError(t, err)
assert.Equal(t, conn.RemotePeer(), respTransport.localID)
b := make([]byte, 6)
_, err = conn.Read(b)
assert.NoError(t, err)
assert.Equal(t, b, []byte("foobar"))
}()

_, _ = respTransport.SecureInbound(context.TODO(), resp)
<-done
conn, err := respTransport.SecureInbound(context.TODO(), resp, initTransport.localID)
require.NoError(t, err)
require.Equal(t, conn.RemotePeer(), initTransport.localID)
_, err = conn.Write([]byte("foobar"))
require.NoError(t, err)
}

if initErr == nil {
t.Fatal("expected initiator to fail with peer ID mismatch error")
}
func TestPeerIDMismatchOutboundFailsHandshake(t *testing.T) {
initTransport := newTestTransport(t, crypto.Ed25519, 2048)
respTransport := newTestTransport(t, crypto.Ed25519, 2048)
init, resp := newConnPair(t)

errChan := make(chan error)
go func() {
_, err := initTransport.SecureOutbound(context.TODO(), init, "a-random-peer-id")
errChan <- err
}()

_, err := respTransport.SecureInbound(context.TODO(), resp, "")
require.Error(t, err)

initErr := <-errChan
require.Error(t, initErr, "expected initiator to fail with peer ID mismatch error")
require.Contains(t, initErr.Error(), "but remote key matches")
}

func TestPeerIDMismatchInboundFailsHandshake(t *testing.T) {
initTransport := newTestTransport(t, crypto.Ed25519, 2048)
respTransport := newTestTransport(t, crypto.Ed25519, 2048)
init, resp := newConnPair(t)

done := make(chan struct{})
go func() {
defer close(done)
conn, err := initTransport.SecureOutbound(context.TODO(), init, respTransport.localID)
assert.NoError(t, err)
_, err = conn.Read([]byte{0})
assert.Error(t, err)
}()

_, err := respTransport.SecureInbound(context.TODO(), resp, "a-random-peer-id")
require.Error(t, err, "expected responder to fail with peer ID mismatch error")
<-done
}

func makeLargePlaintext(size int) []byte {
Expand Down

0 comments on commit df52653

Please sign in to comment.