diff --git a/config/config.go b/config/config.go index e01970baf3..bee597545b 100644 --- a/config/config.go +++ b/config/config.go @@ -193,10 +193,10 @@ func (cfg *Config) addTransports(h host.Host) error { fxopts = append(fxopts, fx.Provide( fx.Annotate( - func(id peer.ID, priv crypto.PrivKey) sec.SecureTransport { - return insecure.NewWithIdentity(insecure.ID, id, priv) + func(id peer.ID, priv crypto.PrivKey) []sec.SecureTransport { + return []sec.SecureTransport{insecure.NewWithIdentity(insecure.ID, id, priv)} }, - fx.ResultTags(`group:"security"`), + fx.ResultTags(`name:"security"`), ), ), ) diff --git a/p2p/test/muxer-negotiation/muxer_test.go b/p2p/test/negotiation/muxer_test.go similarity index 99% rename from p2p/test/muxer-negotiation/muxer_test.go rename to p2p/test/negotiation/muxer_test.go index 2bfb880615..9fc13fd312 100644 --- a/p2p/test/muxer-negotiation/muxer_test.go +++ b/p2p/test/negotiation/muxer_test.go @@ -1,4 +1,4 @@ -package muxer_negotiation +package negotiation import ( "context" diff --git a/p2p/test/negotiation/security_test.go b/p2p/test/negotiation/security_test.go new file mode 100644 index 0000000000..3c309e2422 --- /dev/null +++ b/p2p/test/negotiation/security_test.go @@ -0,0 +1,90 @@ +package negotiation + +import ( + "context" + "crypto/rand" + "testing" + + "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" + "github.com/libp2p/go-libp2p/p2p/security/noise" + tls "github.com/libp2p/go-libp2p/p2p/security/tls" + "github.com/libp2p/go-libp2p/p2p/transport/tcp" + + "github.com/stretchr/testify/require" +) + +var ( + noiseOpt = libp2p.Security("/noise", noise.New) + tlsOpt = libp2p.Security("/tls", tls.New) +) + +func TestSecurityNegotiation(t *testing.T) { + testcases := []testcase{ + { + Name: "server and client have the same preference", + ServerPreference: []libp2p.Option{tlsOpt, noiseOpt}, + ClientPreference: []libp2p.Option{tlsOpt, noiseOpt}, + Expected: "/tls", + }, + { + Name: "client only supports one security", + ServerPreference: []libp2p.Option{tlsOpt, noiseOpt}, + ClientPreference: []libp2p.Option{noiseOpt}, + Expected: "/noise", + }, + { + Name: "server only supports one security", + ServerPreference: []libp2p.Option{noiseOpt}, + ClientPreference: []libp2p.Option{tlsOpt, noiseOpt}, + Expected: "/noise", + }, + { + Name: "no overlap", + ServerPreference: []libp2p.Option{noiseOpt}, + ClientPreference: []libp2p.Option{tlsOpt}, + Error: "failed to negotiate security protocol: protocol not supported", + }, + } + + clientID, _, err := crypto.GenerateEd25519Key(rand.Reader) + require.NoError(t, err) + serverID, _, err := crypto.GenerateEd25519Key(rand.Reader) + require.NoError(t, err) + + for _, tc := range testcases { + tc := tc + + t.Run(tc.Name, func(t *testing.T) { + server, err := libp2p.New( + libp2p.Identity(serverID), + libp2p.ChainOptions(tc.ServerPreference...), + libp2p.Transport(tcp.NewTCPTransport), + libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/0"), + ) + require.NoError(t, err) + + client, err := libp2p.New( + libp2p.Identity(clientID), + libp2p.ChainOptions(tc.ClientPreference...), + libp2p.Transport(tcp.NewTCPTransport), + libp2p.NoListenAddrs, + ) + require.NoError(t, err) + + err = client.Connect(context.Background(), peer.AddrInfo{ID: server.ID(), Addrs: server.Addrs()}) + if tc.Error != "" { + require.Error(t, err) + require.ErrorContains(t, err, tc.Error) + return + } + + require.NoError(t, err) + conns := client.Network().ConnsToPeer(server.ID()) + require.Len(t, conns, 1, "expected exactly one connection") + require.Equal(t, tc.Expected, protocol.ID(conns[0].ConnState().Security)) + }) + } +}