szaydel
4/1/2020 - 9:57 PM

Golang Simple TLS server

package main

import (
	"crypto/tls"
	"fmt"
	"log"
	"net/http"
	"os"
	"time"
)

/*
To test we first want to generate a private and public key. These are for
testing only, self-signed. Depending upon which ciphers we want to test,
we generate either with `genrsa`, this is the most common type, or use
Elliptic curves with `ecparam`, which will use one of the ECDHE ciphers.

Genereate private key:
openssl genrsa -out server.key 2048
openssl ecparam -genkey -name secp384r1 -out server.key
openssl ecparam -genkey -name secp521r1 -out server.key

Generate public key:
openssl req -new -x509 -sha256 -key server.key -out server.crt -days 365

Testing this with openssl:
openssl s_client -connect localhost:4443 -cipher AES128-GCM-SHA256 -tls1_2

Value for -cipher could be one or more ciphers obtained with:
openssl ciphers TLSv1.2

After making connection with curl, enter the following lines to validate
that the server returns a response.

GET / HTTP/1.1
Host: www.example.com
User-Agent: Sam-agent
*/

type empty struct{}

func (h *empty) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "This is a test")
}

var cfg = &tls.Config{
	// MinVersion: tls.VersionTLS10,
	MinVersion:               tls.VersionTLS11,
	MaxVersion:               tls.VersionTLS12,
	CurvePreferences:         []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
	PreferServerCipherSuites: true,
	CipherSuites: []uint16{
		tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
		tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
		tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
		tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
		tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
		tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
	},
}

func main() {
	var h = &empty{}

	go func() {
		<-time.After(60 * time.Second)
		os.Exit(0)
	}()
	srv := &http.Server{
		Addr:         ":4443",
		Handler:      h,
		TLSConfig:    cfg,
		TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),
	}
	// Uncomment one of these two to test either with RSA cert or
	// Elliptic curves cert. Private key and cert must be generated first,
	// and names need to match strings here, or these should be changed to match
	// names of private key and cert.
	// log.Fatal(srv.ListenAndServeTLS("server-rsa.crt", "server-rsa.key"))
	log.Fatal(srv.ListenAndServeTLS("server.crt", "server.key"))
}