(April 2017)
If our server has a cert already, use it. Otherwise, for testing, generate a private key and public cert:
$ openssl genpkey -algorithm RSA -out ~/tmp/test.key -pkeyopt rsa_keygen_bits:4096
$ openssl req -new -x509 -sha256 -key ~/tmp/test.key -out ~/tmp/test.crt -days 3650
A very simple HTTPS server:
package main
import (
"net/http"
"log"
)
func TestServer(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte("Serving TLS!\n"))
}
func main() {
http.HandleFunc("/", TestServer)
err := http.ListenAndServeTLS(":4430", "/home/paulgorman/tmp/test.crt", "/home/paulgorman/tmp/test.key", nil)
if err != nil {
log.Fatal(err)
}
}
A server:
package main
import (
"io"
"log"
"crypto/tls"
"net"
"bufio"
)
func main() {
cer, err := tls.LoadX509KeyPair("/home/paulgorman/tmp/test.crt", "/home/paulgorman/tmp/test.key")
if err != nil {
log.Fatal(err)
}
config := &tls.Config{Certificates: []tls.Certificate{cer}}
ln, err := tls.Listen("tcp", ":4430", config)
if err != nil {
log.Fatal(err)
}
defer ln.Close()
for {
conn, err := ln.Accept()
if err != nil {
log.Fatal(err)
}
go handleConnection(conn)
}
}
func handleConnection(conn net.Conn) {
defer conn.Close()
r := bufio.NewReader(conn)
for {
msg, err := r.ReadString('\n')
if err != nil {
if err == io.EOF {
break
}
log.Println(err)
return
}
println(msg)
n, err := conn.Write([]byte("pong\n"))
if err != nil {
log.Println(n, err)
return
}
}
}
The client:
package main
import (
"log"
"crypto/tls"
)
func main() {
log.SetFlags(log.Lshortfile)
conf := &tls.Config{
InsecureSkipVerify: true,
}
conn, err := tls.Dial("tcp", "127.0.0.1:4430", conf)
if err != nil {
log.Println(err)
return
}
defer conn.Close()
n, err := conn.Write([]byte("ping\n"))
if err != nil {
log.Println(n, err)
return
}
buf := make([]byte, 100)
n, err = conn.Read(buf)
if err != nil {
log.Println(n, err)
return
}
println(string(buf[:n]))
}