@@ -3,10 +3,17 @@ package transport_integration
3
3
import (
4
4
"bytes"
5
5
"context"
6
+ "crypto/ecdsa"
7
+ "crypto/elliptic"
6
8
"crypto/rand"
9
+ "crypto/tls"
10
+ "crypto/x509"
11
+ "crypto/x509/pkix"
12
+ "encoding/pem"
7
13
"errors"
8
14
"fmt"
9
15
"io"
16
+ "math/big"
10
17
"net"
11
18
"runtime"
12
19
"strings"
@@ -30,8 +37,9 @@ import (
30
37
"github.com/libp2p/go-libp2p/p2p/net/swarm"
31
38
"github.com/libp2p/go-libp2p/p2p/protocol/ping"
32
39
"github.com/libp2p/go-libp2p/p2p/security/noise"
33
- tls "github.com/libp2p/go-libp2p/p2p/security/tls"
40
+ sectls "github.com/libp2p/go-libp2p/p2p/security/tls"
34
41
libp2pwebrtc "github.com/libp2p/go-libp2p/p2p/transport/webrtc"
42
+ "github.com/libp2p/go-libp2p/p2p/transport/websocket"
35
43
"go.uber.org/mock/gomock"
36
44
37
45
ma "github.com/multiformats/go-multiaddr"
@@ -48,6 +56,7 @@ type TransportTestCaseOpts struct {
48
56
NoRcmgr bool
49
57
ConnGater connmgr.ConnectionGater
50
58
ResourceManager network.ResourceManager
59
+ HostSeed string
51
60
}
52
61
53
62
func transformOpts (opts TransportTestCaseOpts ) []config.Option {
@@ -87,7 +96,7 @@ var transportsToTest = []TransportTestCase{
87
96
Name : "TCP / TLS / Yamux" ,
88
97
HostGenerator : func (t * testing.T , opts TransportTestCaseOpts ) host.Host {
89
98
libp2pOpts := transformOpts (opts )
90
- libp2pOpts = append (libp2pOpts , libp2p .Security (tls .ID , tls .New ))
99
+ libp2pOpts = append (libp2pOpts , libp2p .Security (sectls .ID , sectls .New ))
91
100
libp2pOpts = append (libp2pOpts , libp2p .Muxer (yamux .ID , yamux .DefaultTransport ))
92
101
if opts .NoListen {
93
102
libp2pOpts = append (libp2pOpts , libp2p .NoListenAddrs )
@@ -113,6 +122,26 @@ var transportsToTest = []TransportTestCase{
113
122
return h
114
123
},
115
124
},
125
+ {
126
+ Name : "Secure WebSocket with CA Certificate" ,
127
+ HostGenerator : func (t * testing.T , opts TransportTestCaseOpts ) host.Host {
128
+ libp2pOpts := transformOpts (opts )
129
+ wsOpts := []interface {}{websocket .WithTLSClientConfig (& tls.Config {InsecureSkipVerify : true })}
130
+ if opts .NoListen {
131
+ libp2pOpts = append (libp2pOpts , libp2p .NoListenAddrs )
132
+ } else {
133
+ dnsName := fmt .Sprintf ("example%s.com" , opts .HostSeed )
134
+ cert , err := generateSelfSignedCert (dnsName )
135
+ require .NoError (t , err )
136
+ libp2pOpts = append (libp2pOpts , libp2p .ListenAddrStrings (fmt .Sprintf ("/ip4/127.0.0.1/tcp/0/tls/sni/%s/ws" , dnsName )))
137
+ wsOpts = append (wsOpts , websocket .WithTLSConfig (& tls.Config {Certificates : []tls.Certificate {cert }}))
138
+ }
139
+ libp2pOpts = append (libp2pOpts , libp2p .Transport (websocket .New , wsOpts ... ))
140
+ h , err := libp2p .New (libp2pOpts ... )
141
+ require .NoError (t , err )
142
+ return h
143
+ },
144
+ },
116
145
{
117
146
Name : "QUIC" ,
118
147
HostGenerator : func (t * testing.T , opts TransportTestCaseOpts ) host.Host {
@@ -158,6 +187,46 @@ var transportsToTest = []TransportTestCase{
158
187
},
159
188
}
160
189
190
+ func generateSelfSignedCert (dnsName string ) (tls.Certificate , error ) {
191
+ priv , err := ecdsa .GenerateKey (elliptic .P256 (), rand .Reader )
192
+ if err != nil {
193
+ return tls.Certificate {}, err
194
+ }
195
+
196
+ serialNumber , err := rand .Int (rand .Reader , new (big.Int ).Lsh (big .NewInt (1 ), 128 ))
197
+ if err != nil {
198
+ return tls.Certificate {}, err
199
+ }
200
+
201
+ template := x509.Certificate {
202
+ SerialNumber : serialNumber ,
203
+ Subject : pkix.Name {
204
+ Organization : []string {"My Organization" },
205
+ },
206
+ NotBefore : time .Now (),
207
+ NotAfter : time .Now ().Add (365 * 24 * time .Hour ), // Valid for 1 year
208
+ KeyUsage : x509 .KeyUsageKeyEncipherment | x509 .KeyUsageDigitalSignature ,
209
+ ExtKeyUsage : []x509.ExtKeyUsage {x509 .ExtKeyUsageServerAuth },
210
+ BasicConstraintsValid : true ,
211
+ DNSNames : []string {dnsName },
212
+ }
213
+
214
+ certDER , err := x509 .CreateCertificate (rand .Reader , & template , & template , & priv .PublicKey , priv )
215
+ if err != nil {
216
+ return tls.Certificate {}, err
217
+ }
218
+
219
+ certPEM := pem .EncodeToMemory (& pem.Block {Type : "CERTIFICATE" , Bytes : certDER })
220
+ privDER , err := x509 .MarshalECPrivateKey (priv )
221
+ if err != nil {
222
+ return tls.Certificate {}, err
223
+ }
224
+ privPEM := pem .EncodeToMemory (& pem.Block {Type : "EC PRIVATE KEY" , Bytes : privDER })
225
+
226
+ // Load the certificate and key into tls.Certificate
227
+ return tls .X509KeyPair (certPEM , privPEM )
228
+ }
229
+
161
230
func TestPing (t * testing.T ) {
162
231
for _ , tc := range transportsToTest {
163
232
t .Run (tc .Name , func (t * testing.T ) {
@@ -798,3 +867,29 @@ func TestConnClosedWhenRemoteCloses(t *testing.T) {
798
867
})
799
868
}
800
869
}
870
+
871
+ func TestConnMatchingAddress (t * testing.T ) {
872
+ for _ , tc := range transportsToTest {
873
+ t .Run (tc .Name , func (t * testing.T ) {
874
+ server := tc .HostGenerator (t , TransportTestCaseOpts {})
875
+ client1 := tc .HostGenerator (t , TransportTestCaseOpts {NoListen : true })
876
+ client2 := tc .HostGenerator (t , TransportTestCaseOpts {NoListen : true })
877
+ defer server .Close ()
878
+ defer client1 .Close ()
879
+ defer client2 .Close ()
880
+
881
+ client1 .Peerstore ().AddAddrs (server .ID (), server .Addrs (), peerstore .PermanentAddrTTL )
882
+ ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
883
+ defer cancel ()
884
+ err := client1 .Connect (ctx , peer.AddrInfo {ID : server .ID (), Addrs : server .Addrs ()})
885
+ require .NoError (t , err )
886
+
887
+ client1Conns := client1 .Network ().ConnsToPeer (server .ID ())
888
+ require .Equal (t , 1 , len (client1Conns ))
889
+ remoteMA := client1Conns [0 ].RemoteMultiaddr ()
890
+
891
+ err = client2 .Connect (ctx , peer.AddrInfo {ID : server .ID (), Addrs : []ma.Multiaddr {remoteMA }})
892
+ require .NoError (t , err )
893
+ })
894
+ }
895
+ }
0 commit comments