Commit 7cc4ecf8 authored by Boris Mühmer's avatar Boris Mühmer
Browse files

imported tls example with minor modifications for local setup

parent 8723c896
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
# perplex

Perplex is a simple client-server demo.

## Notes

* [TLS server and client](https://gist.github.com/spikebike/2232102)
 No newline at end of file
+44 −0
Original line number Diff line number Diff line
@@ -2,12 +2,22 @@ package main

import (
	"bufio"
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io"
	"log"
	"net"
)

func main() {
	log.Printf("Started perplex client.")

	//tcpClient()
	tlsClient()
}

func tcpClient() {
	conn, err := net.Dial("tcp", "localhost:4321")
	if err != nil {
		log.Panic(err)
@@ -32,3 +42,37 @@ func disconnect(conn net.Conn) {
	defer conn.Close()
	log.Printf("Disconnecting from: %v->%v", conn.LocalAddr(), conn.RemoteAddr())
}

func tlsClient() {
	cert, err := tls.LoadX509KeyPair("../../scripts/certs/client.pem", "../../scripts/certs/client.key")
	if err != nil {
		log.Fatalf("server: loadkeys: %s", err)
	}
	config := tls.Config{Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true}
	conn, err := tls.Dial("tcp", "localhost:4322", &config)
	if err != nil {
		log.Fatalf("client: dial: %s", err)
	}
	defer conn.Close()
	log.Println("client: connected to: ", conn.RemoteAddr())

	state := conn.ConnectionState()
	for _, v := range state.PeerCertificates {
		fmt.Println(x509.MarshalPKIXPublicKey(v.PublicKey))
		fmt.Println(v.Subject)
	}
	log.Println("client: handshake: ", state.HandshakeComplete)
	log.Println("client: mutual: ", state.NegotiatedProtocolIsMutual)

	message := "Hello\n"
	n, err := io.WriteString(conn, message)
	if err != nil {
		log.Fatalf("client: write: %s", err)
	}
	log.Printf("client: wrote %q (%d bytes)", message, n)

	reply := make([]byte, 256)
	n, err = conn.Read(reply)
	log.Printf("client: read %q (%d bytes)", string(reply[:n]), n)
	log.Print("client: exiting")
}
+70 −3
Original line number Diff line number Diff line
@@ -2,15 +2,24 @@ package main

import (
	"bufio"
	"crypto/rand"
	"crypto/tls"
	"crypto/x509"
	"log"
	"net"
)

func main() {
	log.Printf("Started perplex server.")

	//tcpServer()
	tlsServer()
}

func tcpServer() {
	ln, err := net.Listen("tcp", ":4321")
	if err != nil {
		log.Panic(err)
		log.Fatal(err)
	}
	defer ln.Close()
	for {
@@ -18,11 +27,11 @@ func main() {
		if err != nil {
			log.Printf("Accept() failed with: %v", err)
		}
		go handleConnection(conn)
		go handleTCPClient(conn)
	}
}

func handleConnection(conn net.Conn) {
func handleTCPClient(conn net.Conn) {
	defer disconnect(conn)
	log.Printf("Connected from: %v->%v", conn.RemoteAddr(), conn.LocalAddr())
	banner := "Welcome to perplex!\n"
@@ -58,3 +67,61 @@ func disconnect(conn net.Conn) {
	defer conn.Close()
	log.Printf("Disconnected from: %v->%v", conn.RemoteAddr(), conn.LocalAddr())
}

func tlsServer() {
	cert, err := tls.LoadX509KeyPair("../../scripts/certs/server.pem", "../../scripts/certs/server.key")
	if err != nil {
		log.Fatalf("server: loadkeys: %s", err)
	}
	config := tls.Config{Certificates: []tls.Certificate{cert}}
	config.Rand = rand.Reader
	listener, err := tls.Listen("tcp", ":4322", &config)
	if err != nil {
		log.Fatal(err)
	}
	log.Print("server: listening")
	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Printf("server: accept: %s", err)
			break
		}
		defer conn.Close()
		log.Printf("server: accepted from %s", conn.RemoteAddr())
		tlscon, ok := conn.(*tls.Conn)
		if ok {
			log.Print("ok=true")
			state := tlscon.ConnectionState()
			for _, v := range state.PeerCertificates {
				log.Print(x509.MarshalPKIXPublicKey(v.PublicKey))
			}
		}
		go handleTLSClient(conn)
	}
}

func handleTLSClient(conn net.Conn) {
	defer conn.Close()
	buf := make([]byte, 512)
	for {
		log.Print("server: conn: waiting")
		n, err := conn.Read(buf)
		if err != nil {
			if err != nil {
				log.Printf("server: conn: read: %s", err)
			}
			break
		}
		log.Printf("server: conn: echo %q\n", string(buf[:n]))
		n, err = conn.Write(buf[:n])

		n, err = conn.Write(buf[:n])
		log.Printf("server: conn: wrote %d bytes", n)

		if err != nil {
			log.Printf("server: write: %s", err)
			break
		}
	}
	log.Println("server: conn: closed")
}

scripts/.gitignore

0 → 100644
+1 −0
Original line number Diff line number Diff line
certs/*

scripts/makecert

0 → 100755
+10 −0
Original line number Diff line number Diff line
#!/bin/bash
# call this script with an email address (valid or not).
# like:
# ./makecert joe@example.com
mkdir certs
rm certs/*
echo "make server cert"
openssl req -new -nodes -x509 -out certs/server.pem -keyout certs/server.key -days 3650 -subj "/C=DE/ST=NRW/L=Earth/O=Random Company/OU=IT/CN=www.random.com/emailAddress=$1"
echo "make client cert"
openssl req -new -nodes -x509 -out certs/client.pem -keyout certs/client.key -days 3650 -subj "/C=DE/ST=NRW/L=Earth/O=Random Company/OU=IT/CN=www.random.com/emailAddress=$1"