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

Commit

Permalink
Merge pull request #67 from libp2p/tls-handshake
Browse files Browse the repository at this point in the history
use the handshake logic from go-libp2p-tls
  • Loading branch information
marten-seemann authored Aug 5, 2019
2 parents 837eddb + 8067d71 commit fd198fe
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 230 deletions.
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@

This is an implementation of the [libp2p transport](https://github.com/libp2p/go-libp2p-transport/blob/master/transport.go) and the [libp2p stream muxer](https://github.com/libp2p/go-stream-muxer) using QUIC.

## Known limitations

* currently only works with RSA host keys

---

The last gx published version of this module was:
79 changes: 19 additions & 60 deletions conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import (
"bytes"
"context"
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
mrand "math/rand"
"time"

ic "github.com/libp2p/go-libp2p-core/crypto"
Expand All @@ -26,12 +25,26 @@ var _ = Describe("Connection", func() {
)

createPeer := func() (peer.ID, ic.PrivKey) {
key, err := rsa.GenerateKey(rand.Reader, 1024)
Expect(err).ToNot(HaveOccurred())
priv, err := ic.UnmarshalRsaPrivateKey(x509.MarshalPKCS1PrivateKey(key))
var priv ic.PrivKey
var err error
switch mrand.Int() % 4 {
case 0:
fmt.Fprintf(GinkgoWriter, " using an ECDSA key: ")
priv, _, err = ic.GenerateECDSAKeyPair(rand.Reader)
case 1:
fmt.Fprintf(GinkgoWriter, " using an RSA key: ")
priv, _, err = ic.GenerateRSAKeyPair(1024, rand.Reader)
case 2:
fmt.Fprintf(GinkgoWriter, " using an Ed25519 key: ")
priv, _, err = ic.GenerateEd25519Key(rand.Reader)
case 3:
fmt.Fprintf(GinkgoWriter, " using an secp256k1 key: ")
priv, _, err = ic.GenerateSecp256k1Key(rand.Reader)
}
Expect(err).ToNot(HaveOccurred())
id, err := peer.IDFromPrivateKey(priv)
Expect(err).ToNot(HaveOccurred())
fmt.Fprintln(GinkgoWriter, id.Pretty())
return id, priv
}

Expand All @@ -52,11 +65,6 @@ var _ = Describe("Connection", func() {
return <-addrChan, connChan
}

// modify the cert chain such that verificiation will fail
invalidateCertChain := func(tlsConf *tls.Config) {
tlsConf.Certificates[0].Certificate = [][]byte{tlsConf.Certificates[0].Certificate[0]}
}

BeforeEach(func() {
serverID, serverKey = createPeer()
clientID, clientKey = createPeer()
Expand Down Expand Up @@ -141,55 +149,6 @@ var _ = Describe("Connection", func() {
Consistently(serverConnChan).ShouldNot(Receive())
})

It("fails if the client presents an invalid cert chain", func() {
serverTransport, err := NewTransport(serverKey)
Expect(err).ToNot(HaveOccurred())
serverAddr, serverConnChan := runServer(serverTransport, "/ip4/127.0.0.1/udp/0/quic")

clientTransport, err := NewTransport(clientKey)
invalidateCertChain(clientTransport.(*transport).tlsConf)
Expect(err).ToNot(HaveOccurred())
conn, err := clientTransport.Dial(context.Background(), serverAddr, serverID)
Expect(err).ToNot(HaveOccurred())
Eventually(func() bool { return conn.IsClosed() }).Should(BeTrue())
Consistently(serverConnChan).ShouldNot(Receive())
})

It("fails if the server presents an invalid cert chain", func() {
serverTransport, err := NewTransport(serverKey)
invalidateCertChain(serverTransport.(*transport).tlsConf)
Expect(err).ToNot(HaveOccurred())
serverAddr, serverConnChan := runServer(serverTransport, "/ip4/127.0.0.1/udp/0/quic")

clientTransport, err := NewTransport(clientKey)
Expect(err).ToNot(HaveOccurred())
_, err = clientTransport.Dial(context.Background(), serverAddr, serverID)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("CRYPTO_ERROR"))
Consistently(serverConnChan).ShouldNot(Receive())
})

It("keeps accepting connections after a failed connection attempt", func() {
serverTransport, err := NewTransport(serverKey)
Expect(err).ToNot(HaveOccurred())
serverAddr, serverConnChan := runServer(serverTransport, "/ip4/127.0.0.1/udp/0/quic")

// first dial with an invalid cert chain
clientTransport1, err := NewTransport(clientKey)
invalidateCertChain(clientTransport1.(*transport).tlsConf)
Expect(err).ToNot(HaveOccurred())
_, err = clientTransport1.Dial(context.Background(), serverAddr, serverID)
Expect(err).ToNot(HaveOccurred())
Consistently(serverConnChan).ShouldNot(Receive())

// then dial with a valid client
clientTransport2, err := NewTransport(clientKey)
Expect(err).ToNot(HaveOccurred())
_, err = clientTransport2.Dial(context.Background(), serverAddr, serverID)
Expect(err).ToNot(HaveOccurred())
Eventually(serverConnChan).Should(Receive())
})

It("dials to two servers at the same time", func() {
serverID2, serverKey2 := createPeer()

Expand Down
123 changes: 0 additions & 123 deletions crypto.go

This file was deleted.

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module github.com/libp2p/go-libp2p-quic-transport

require (
github.com/gogo/protobuf v1.2.1
github.com/libp2p/go-libp2p-core v0.0.1
github.com/libp2p/go-libp2p-tls v0.1.1
github.com/lucas-clemente/quic-go v0.12.0
github.com/multiformats/go-multiaddr v0.0.4
github.com/multiformats/go-multiaddr-net v0.0.1
Expand Down
11 changes: 4 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
Expand All @@ -40,6 +39,8 @@ github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6
github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8=
github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I=
github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco=
github.com/libp2p/go-libp2p-tls v0.1.1 h1:tjW7njTM8JX8FbEvqr8/VSKBdZYZ7CtGtv3i6NiFf10=
github.com/libp2p/go-libp2p-tls v0.1.1/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M=
github.com/lucas-clemente/quic-go v0.12.0 h1:dYHUyB50gEQlK3KqytmNySzuyzAcaQ3iuI2ZReAfVrE=
github.com/lucas-clemente/quic-go v0.12.0/go.mod h1:UXJJPE4RfFef/xPO5wQm0tITK8gNfqwTxjbE7s3Vb8s=
github.com/marten-seemann/qpack v0.1.0/go.mod h1:LFt1NU/Ptjip0C2CPkhimBz5CGE3WGDAUWqna+CNTrI=
Expand All @@ -49,14 +50,11 @@ github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ=
github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U=
github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ=
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs=
github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY=
github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44=
github.com/multiformats/go-multiaddr v0.0.2 h1:RBysRCv5rv3FWlhKWKoXv8tnsCUpEpIZpCmqAGZos2s=
github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44=
github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4=
github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44=
Expand All @@ -80,11 +78,9 @@ github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg5
github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M=
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28DveNzzgmbXR+ENoPjUeIU=
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190228165749-92fc7df08ae7 h1:Qe/u+eY379X4He4GBMFZYu3pmh1ML5yT1aL1ndNM1zQ=
golang.org/x/net v0.0.0-20190228165749-92fc7df08ae7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand All @@ -93,8 +89,9 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c=
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09 h1:IlD35wZE03o2qJy2o37WIskL33b7PT6cHdGnE8bieZs=
golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand Down
6 changes: 6 additions & 0 deletions libp2pquic_suite_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package libp2pquic

import (
mrand "math/rand"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

Expand All @@ -11,3 +13,7 @@ func TestLibp2pQuicTransport(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "libp2p QUIC Transport Suite")
}

var _ = BeforeSuite(func() {
mrand.Seed(GinkgoRandomSeed())
})
22 changes: 17 additions & 5 deletions listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ import (
ic "github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/peer"
tpt "github.com/libp2p/go-libp2p-core/transport"
p2ptls "github.com/libp2p/go-libp2p-tls"

quic "github.com/lucas-clemente/quic-go"
ma "github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr-net"
)

var quicListenAddr = quic.ListenAddr

// A listener listens for QUIC connections.
type listener struct {
quicListener quic.Listener
Expand All @@ -28,7 +27,16 @@ type listener struct {

var _ tpt.Listener = &listener{}

func newListener(addr ma.Multiaddr, transport tpt.Transport, localPeer peer.ID, key ic.PrivKey, tlsConf *tls.Config) (tpt.Listener, error) {
func newListener(addr ma.Multiaddr, transport tpt.Transport, localPeer peer.ID, key ic.PrivKey, identity *p2ptls.Identity) (tpt.Listener, error) {
var tlsConf tls.Config
tlsConf.GetConfigForClient = func(_ *tls.ClientHelloInfo) (*tls.Config, error) {
// return a tls.Config that verifies the peer's certificate chain.
// Note that since we have no way of associating an incoming QUIC connection with
// the peer ID calculated here, we don't actually receive the peer's public key
// from the key chan.
conf, _ := identity.ConfigForAny()
return conf, nil
}
lnet, host, err := manet.DialArgs(addr)
if err != nil {
return nil, err
Expand All @@ -41,7 +49,7 @@ func newListener(addr ma.Multiaddr, transport tpt.Transport, localPeer peer.ID,
if err != nil {
return nil, err
}
ln, err := quic.Listen(conn, tlsConf, quicConfig)
ln, err := quic.Listen(conn, &tlsConf, quicConfig)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -75,7 +83,11 @@ func (l *listener) Accept() (tpt.CapableConn, error) {
}

func (l *listener) setupConn(sess quic.Session) (tpt.CapableConn, error) {
remotePubKey, err := getRemotePubKey(sess.ConnectionState().PeerCertificates)
// The tls.Config used to establish this connection already verified the certificate chain.
// Since we don't have any way of knowing which tls.Config was used though,
// we have to re-determine the peer's identity here.
// Therefore, this is expected to never fail.
remotePubKey, err := p2ptls.PubKeyFromCertChain(sess.ConnectionState().PeerCertificates)
if err != nil {
return nil, err
}
Expand Down
1 change: 1 addition & 0 deletions listener_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ var _ = Describe("Listener", func() {
Context("listening on the right address", func() {
It("returns the address it is listening on", func() {
localAddr, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/0/quic")
Expect(err).ToNot(HaveOccurred())
ln, err := t.Listen(localAddr)
Expect(err).ToNot(HaveOccurred())
netAddr := ln.Addr()
Expand Down
Loading

0 comments on commit fd198fe

Please sign in to comment.