From 6d7a3968cdf65f589e0638a9d8542cc3dbfdbaee Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 19 Apr 2022 11:42:05 +0200 Subject: [PATCH] feat: catch panics in TLS negotiation Part of https://github.com/libp2p/go-libp2p/issues/1389 --- p2p/security/tls/crypto.go | 12 +++++++++++- p2p/security/tls/transport.go | 13 ++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/p2p/security/tls/crypto.go b/p2p/security/tls/crypto.go index f3502aa740..24a06939ee 100644 --- a/p2p/security/tls/crypto.go +++ b/p2p/security/tls/crypto.go @@ -11,6 +11,8 @@ import ( "errors" "fmt" "math/big" + "os" + "runtime/debug" "time" "golang.org/x/sys/cpu" @@ -72,7 +74,15 @@ func (i *Identity) ConfigForPeer(remote peer.ID) (*tls.Config, <-chan ic.PubKey) conf := i.config.Clone() // We're using InsecureSkipVerify, so the verifiedChains parameter will always be empty. // We need to parse the certificates ourselves from the raw certs. - conf.VerifyPeerCertificate = func(rawCerts [][]byte, _ [][]*x509.Certificate) error { + conf.VerifyPeerCertificate = func(rawCerts [][]byte, _ [][]*x509.Certificate) (err error) { + defer func() { + if rerr := recover(); rerr != nil { + fmt.Fprintf(os.Stderr, "panic when processing peer certificate in TLS handshake: %s\n%s\n", rerr, debug.Stack()) + err = fmt.Errorf("panic when processing peer certificate in TLS handshake: %s", rerr) + + } + }() + defer close(keyCh) chain := make([]*x509.Certificate, len(rawCerts)) diff --git a/p2p/security/tls/transport.go b/p2p/security/tls/transport.go index 85e75a1587..fcdbd3c676 100644 --- a/p2p/security/tls/transport.go +++ b/p2p/security/tls/transport.go @@ -4,7 +4,10 @@ import ( "context" "crypto/tls" "errors" + "fmt" "net" + "os" + "runtime/debug" ci "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/peer" @@ -70,7 +73,15 @@ func (t *Transport) SecureOutbound(ctx context.Context, insecure net.Conn, p pee return cs, err } -func (t *Transport) handshake(ctx context.Context, tlsConn *tls.Conn, keyCh <-chan ci.PubKey) (sec.SecureConn, error) { +func (t *Transport) handshake(ctx context.Context, tlsConn *tls.Conn, keyCh <-chan ci.PubKey) (_sconn sec.SecureConn, err error) { + defer func() { + if rerr := recover(); rerr != nil { + fmt.Fprintf(os.Stderr, "panic in TLS handshake: %s\n%s\n", rerr, debug.Stack()) + err = fmt.Errorf("panic in TLS handshake: %s", rerr) + + } + }() + if err := tlsConn.HandshakeContext(ctx); err != nil { return nil, err }