From 7b8ba83168a064df9e30d6eaf3c53af038bcc26b Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 20 Feb 2019 17:44:39 +0800 Subject: [PATCH 1/3] add an example server and client --- example/README.md | 6 ++++ example/client/main.go | 68 +++++++++++++++++++++++++++++++++++++++ example/server/main.go | 73 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 example/README.md create mode 100644 example/client/main.go create mode 100644 example/server/main.go diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..dff0f66 --- /dev/null +++ b/example/README.md @@ -0,0 +1,6 @@ +# TLS handshake example + +Run +```bash +go run example/server/main.go +``` diff --git a/example/client/main.go b/example/client/main.go new file mode 100644 index 0000000..7e8ffca --- /dev/null +++ b/example/client/main.go @@ -0,0 +1,68 @@ +package main + +import ( + "context" + "crypto/rand" + "flag" + "fmt" + "io/ioutil" + "net" + "time" + + ic "github.com/libp2p/go-libp2p-crypto" + peer "github.com/libp2p/go-libp2p-peer" + libp2ptls "github.com/libp2p/go-libp2p-tls" +) + +func main() { + if err := startClient(); err != nil { + panic(err) + } +} + +func startClient() error { + port := flag.Int("p", 5533, "port") + peerIDString := flag.String("id", "", "peer ID") + flag.Parse() + + peerID, err := peer.IDB58Decode(*peerIDString) + if err != nil { + return err + } + + priv, _, err := ic.GenerateECDSAKeyPair(rand.Reader) + if err != nil { + return err + } + id, err := peer.IDFromPrivateKey(priv) + if err != nil { + return err + } + fmt.Printf("Generated new peer with an ECDSA key. Peer ID: %s\n", id.Pretty()) + tp, err := libp2ptls.New(priv) + if err != nil { + return err + } + + remoteAddr := fmt.Sprintf("localhost:%d", *port) + fmt.Printf("Dialing %s\n", remoteAddr) + conn, err := net.Dial("tcp", remoteAddr) + if err != nil { + return err + } + fmt.Printf("Dialed raw connection to %s\n", conn.RemoteAddr()) + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + sconn, err := tp.SecureOutbound(ctx, conn, peerID) + if err != nil { + return err + } + fmt.Printf("Authenticated server: %s\n", sconn.RemotePeer().Pretty()) + data, err := ioutil.ReadAll(sconn) + if err != nil { + return err + } + fmt.Printf("Received message from server: %s\n", string(data)) + return nil +} diff --git a/example/server/main.go b/example/server/main.go new file mode 100644 index 0000000..d837165 --- /dev/null +++ b/example/server/main.go @@ -0,0 +1,73 @@ +package main + +import ( + "context" + "crypto/rand" + "flag" + "fmt" + "net" + "time" + + ic "github.com/libp2p/go-libp2p-crypto" + peer "github.com/libp2p/go-libp2p-peer" + libp2ptls "github.com/libp2p/go-libp2p-tls" +) + +func main() { + if err := startServer(); err != nil { + panic(err) + } +} + +func startServer() error { + port := flag.Int("p", 5533, "port") + flag.Parse() + + priv, _, err := ic.GenerateECDSAKeyPair(rand.Reader) + if err != nil { + return err + } + id, err := peer.IDFromPrivateKey(priv) + if err != nil { + return err + } + fmt.Printf("Generated new peer with an ECDSA key. Peer ID: %s\n", id.Pretty()) + tp, err := libp2ptls.New(priv) + if err != nil { + return err + } + + ln, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", *port)) + if err != nil { + return err + } + fmt.Printf("Listening for new connections on %s\n", ln.Addr()) + fmt.Printf("Now run the following command in a separate terminal:\n") + fmt.Printf("\tgo run example/client/main.go -p %d -id %s\n", *port, id.Pretty()) + + for { + conn, err := ln.Accept() + if err != nil { + return err + } + fmt.Printf("Accepted raw connection from %s\n", conn.RemoteAddr()) + go func() { + if err := handleConn(tp, conn); err != nil { + fmt.Printf("Error handling connection from %s: %s\n", conn.RemoteAddr(), err) + } + }() + } +} + +func handleConn(tp *libp2ptls.Transport, conn net.Conn) error { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + sconn, err := tp.SecureInbound(ctx, conn) + if err != nil { + return err + } + fmt.Printf("Authenticated client: %s\n", sconn.RemotePeer().Pretty()) + fmt.Fprintf(sconn, "Hello client!") + fmt.Printf("Closing connection to %s\n", conn.RemoteAddr()) + return sconn.Close() +} From 46b3204136346e4263d3f2163d0808223b15b423 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 20 Feb 2019 18:10:23 +0800 Subject: [PATCH 2/3] add a command line flag to set the key type --- example/client/main.go | 25 ++++++++++++++++++++++--- example/server/main.go | 23 +++++++++++++++++++++-- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/example/client/main.go b/example/client/main.go index 7e8ffca..678ece6 100644 --- a/example/client/main.go +++ b/example/client/main.go @@ -23,22 +23,41 @@ func main() { func startClient() error { port := flag.Int("p", 5533, "port") peerIDString := flag.String("id", "", "peer ID") + keyType := flag.String("key", "ecdsa", "rsa, ecdsa, ed25519 or secp256k1") flag.Parse() - peerID, err := peer.IDB58Decode(*peerIDString) + var priv ic.PrivKey + var err error + switch *keyType { + case "rsa": + fmt.Printf("Generated new peer with an RSA key.") + priv, _, err = ic.GenerateRSAKeyPair(2048, rand.Reader) + case "ecdsa": + fmt.Printf("Generated new peer with an ECDSA key.") + priv, _, err = ic.GenerateECDSAKeyPair(rand.Reader) + case "ed25519": + fmt.Printf("Generated new peer with an Ed25519 key.") + priv, _, err = ic.GenerateEd25519Key(rand.Reader) + case "secp256k1": + fmt.Printf("Generated new peer with an Secp256k1 key.") + priv, _, err = ic.GenerateSecp256k1Key(rand.Reader) + default: + return fmt.Errorf("unknown key type: %s", *keyType) + } if err != nil { return err } - priv, _, err := ic.GenerateECDSAKeyPair(rand.Reader) + peerID, err := peer.IDB58Decode(*peerIDString) if err != nil { return err } + id, err := peer.IDFromPrivateKey(priv) if err != nil { return err } - fmt.Printf("Generated new peer with an ECDSA key. Peer ID: %s\n", id.Pretty()) + fmt.Printf(" Peer ID: %s\n", id.Pretty()) tp, err := libp2ptls.New(priv) if err != nil { return err diff --git a/example/server/main.go b/example/server/main.go index d837165..9988ec0 100644 --- a/example/server/main.go +++ b/example/server/main.go @@ -21,17 +21,36 @@ func main() { func startServer() error { port := flag.Int("p", 5533, "port") + keyType := flag.String("key", "ecdsa", "rsa, ecdsa, ed25519 or secp256k1") flag.Parse() - priv, _, err := ic.GenerateECDSAKeyPair(rand.Reader) + var priv ic.PrivKey + var err error + switch *keyType { + case "rsa": + fmt.Printf("Generated new peer with an RSA key.") + priv, _, err = ic.GenerateRSAKeyPair(2048, rand.Reader) + case "ecdsa": + fmt.Printf("Generated new peer with an ECDSA key.") + priv, _, err = ic.GenerateECDSAKeyPair(rand.Reader) + case "ed25519": + fmt.Printf("Generated new peer with an Ed25519 key.") + priv, _, err = ic.GenerateEd25519Key(rand.Reader) + case "secp256k1": + fmt.Printf("Generated new peer with an Secp256k1 key.") + priv, _, err = ic.GenerateSecp256k1Key(rand.Reader) + default: + return fmt.Errorf("unknown key type: %s", *keyType) + } if err != nil { return err } + id, err := peer.IDFromPrivateKey(priv) if err != nil { return err } - fmt.Printf("Generated new peer with an ECDSA key. Peer ID: %s\n", id.Pretty()) + fmt.Printf(" Peer ID: %s\n", id.Pretty()) tp, err := libp2ptls.New(priv) if err != nil { return err From ea46ae40d32f243a348407e476b5c21a9ebcd77e Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 21 Feb 2019 17:04:59 +0800 Subject: [PATCH 3/3] rename example to cmd, move to a single .go file --- {example => cmd}/README.md | 2 +- cmd/tlsdiag.go | 33 +++++++++++++++++++ .../client/main.go => cmd/tlsdiag/client.go | 31 ++--------------- cmd/tlsdiag/key.go | 28 ++++++++++++++++ .../server/main.go => cmd/tlsdiag/server.go | 33 +++---------------- 5 files changed, 69 insertions(+), 58 deletions(-) rename {example => cmd}/README.md (57%) create mode 100644 cmd/tlsdiag.go rename example/client/main.go => cmd/tlsdiag/client.go (61%) create mode 100644 cmd/tlsdiag/key.go rename example/server/main.go => cmd/tlsdiag/server.go (62%) diff --git a/example/README.md b/cmd/README.md similarity index 57% rename from example/README.md rename to cmd/README.md index dff0f66..d0efa12 100644 --- a/example/README.md +++ b/cmd/README.md @@ -2,5 +2,5 @@ Run ```bash -go run example/server/main.go +go run cmd/tlsdiag.go server ``` diff --git a/cmd/tlsdiag.go b/cmd/tlsdiag.go new file mode 100644 index 0000000..73aef5f --- /dev/null +++ b/cmd/tlsdiag.go @@ -0,0 +1,33 @@ +package main + +import ( + "fmt" + "os" + + "github.com/libp2p/go-libp2p-tls/cmd/cmdimpl" +) + +func main() { + if len(os.Args) <= 1 { + fmt.Println("missing argument: client / server") + return + } + + role := os.Args[1] + // remove the role argument from os.Args + os.Args = append([]string{os.Args[0]}, os.Args[2:]...) + + var err error + switch role { + case "client": + err = cmdimpl.StartClient() + case "server": + err = cmdimpl.StartServer() + default: + fmt.Println("invalid argument. Expected client / server") + return + } + if err != nil { + panic(err) + } +} diff --git a/example/client/main.go b/cmd/tlsdiag/client.go similarity index 61% rename from example/client/main.go rename to cmd/tlsdiag/client.go index 678ece6..9de3347 100644 --- a/example/client/main.go +++ b/cmd/tlsdiag/client.go @@ -1,49 +1,24 @@ -package main +package cmdimpl import ( "context" - "crypto/rand" "flag" "fmt" "io/ioutil" "net" "time" - ic "github.com/libp2p/go-libp2p-crypto" peer "github.com/libp2p/go-libp2p-peer" libp2ptls "github.com/libp2p/go-libp2p-tls" ) -func main() { - if err := startClient(); err != nil { - panic(err) - } -} - -func startClient() error { +func StartClient() error { port := flag.Int("p", 5533, "port") peerIDString := flag.String("id", "", "peer ID") keyType := flag.String("key", "ecdsa", "rsa, ecdsa, ed25519 or secp256k1") flag.Parse() - var priv ic.PrivKey - var err error - switch *keyType { - case "rsa": - fmt.Printf("Generated new peer with an RSA key.") - priv, _, err = ic.GenerateRSAKeyPair(2048, rand.Reader) - case "ecdsa": - fmt.Printf("Generated new peer with an ECDSA key.") - priv, _, err = ic.GenerateECDSAKeyPair(rand.Reader) - case "ed25519": - fmt.Printf("Generated new peer with an Ed25519 key.") - priv, _, err = ic.GenerateEd25519Key(rand.Reader) - case "secp256k1": - fmt.Printf("Generated new peer with an Secp256k1 key.") - priv, _, err = ic.GenerateSecp256k1Key(rand.Reader) - default: - return fmt.Errorf("unknown key type: %s", *keyType) - } + priv, err := generateKey(*keyType) if err != nil { return err } diff --git a/cmd/tlsdiag/key.go b/cmd/tlsdiag/key.go new file mode 100644 index 0000000..fc2ad8a --- /dev/null +++ b/cmd/tlsdiag/key.go @@ -0,0 +1,28 @@ +package cmdimpl + +import ( + "crypto/rand" + "fmt" + + ic "github.com/libp2p/go-libp2p-crypto" +) + +func generateKey(keyType string) (priv ic.PrivKey, err error) { + switch keyType { + case "rsa": + fmt.Printf("Generated new peer with an RSA key.") + priv, _, err = ic.GenerateRSAKeyPair(2048, rand.Reader) + case "ecdsa": + fmt.Printf("Generated new peer with an ECDSA key.") + priv, _, err = ic.GenerateECDSAKeyPair(rand.Reader) + case "ed25519": + fmt.Printf("Generated new peer with an Ed25519 key.") + priv, _, err = ic.GenerateEd25519Key(rand.Reader) + case "secp256k1": + fmt.Printf("Generated new peer with an Secp256k1 key.") + priv, _, err = ic.GenerateSecp256k1Key(rand.Reader) + default: + return nil, fmt.Errorf("unknown key type: %s", keyType) + } + return +} diff --git a/example/server/main.go b/cmd/tlsdiag/server.go similarity index 62% rename from example/server/main.go rename to cmd/tlsdiag/server.go index 9988ec0..b192c44 100644 --- a/example/server/main.go +++ b/cmd/tlsdiag/server.go @@ -1,47 +1,22 @@ -package main +package cmdimpl import ( "context" - "crypto/rand" "flag" "fmt" "net" "time" - ic "github.com/libp2p/go-libp2p-crypto" peer "github.com/libp2p/go-libp2p-peer" libp2ptls "github.com/libp2p/go-libp2p-tls" ) -func main() { - if err := startServer(); err != nil { - panic(err) - } -} - -func startServer() error { +func StartServer() error { port := flag.Int("p", 5533, "port") keyType := flag.String("key", "ecdsa", "rsa, ecdsa, ed25519 or secp256k1") flag.Parse() - var priv ic.PrivKey - var err error - switch *keyType { - case "rsa": - fmt.Printf("Generated new peer with an RSA key.") - priv, _, err = ic.GenerateRSAKeyPair(2048, rand.Reader) - case "ecdsa": - fmt.Printf("Generated new peer with an ECDSA key.") - priv, _, err = ic.GenerateECDSAKeyPair(rand.Reader) - case "ed25519": - fmt.Printf("Generated new peer with an Ed25519 key.") - priv, _, err = ic.GenerateEd25519Key(rand.Reader) - case "secp256k1": - fmt.Printf("Generated new peer with an Secp256k1 key.") - priv, _, err = ic.GenerateSecp256k1Key(rand.Reader) - default: - return fmt.Errorf("unknown key type: %s", *keyType) - } + priv, err := generateKey(*keyType) if err != nil { return err } @@ -62,7 +37,7 @@ func startServer() error { } fmt.Printf("Listening for new connections on %s\n", ln.Addr()) fmt.Printf("Now run the following command in a separate terminal:\n") - fmt.Printf("\tgo run example/client/main.go -p %d -id %s\n", *port, id.Pretty()) + fmt.Printf("\tgo run cmd/tlsdiag.go client -p %d -id %s\n", *port, id.Pretty()) for { conn, err := ln.Accept()