package main
import (
"log"
"crypto/tls"
"net/http"
"fmt"
"flag"
"strconv"
"strings"
)
// Define a string-to-int mapping we can use to convert the command-line
// m/M flags to tls package version constants.
var versions map[string]int = map[string]int {
"TLS10": tls.VersionTLS10,
"TLS11": tls.VersionTLS11,
"TLS12": tls.VersionTLS12,
"TLS13": tls.VersionTLS13,
}
// Define a mapping for command line control of client authentication behavior
var authopts map[string]tls.ClientAuthType = map[string]tls.ClientAuthType {
"NONE": tls.NoClientCert,
"WANT": tls.RequestClientCert,
"NEED": tls.RequireAnyClientCert,
"WANTVFY": tls.VerifyClientCertIfGiven,
"NEEDVFY": tls.RequireAndVerifyClientCert,
}
// This will be the default response handler that will be registered by the
// server for all request patterns. It will give a few simple pieces of
// information about the TLS connection.
func createResponse(w http.ResponseWriter, req *http.Request) {
log.Printf("Completed connection from %v\n", (*req).RemoteAddr)
var bld strings.Builder
w.Header().Set("Content-Type", "text/html")
bld.WriteString("\n")
bld.WriteString("
\nTLS Connection Info\n\n")
bld.WriteString("\nTLS Connection Info
\n")
bld.WriteString("")
bld.WriteString("- Connection From: ")
bld.WriteString((*req).RemoteAddr)
bld.WriteString("\n")
bld.WriteString(fmt.Sprintf("
- Version: 0x%04X
\n",
(*req).TLS.Version))
bld.WriteString(fmt.Sprintf("- Cipher Suite: 0x%04X
\n",
(*req).TLS.CipherSuite))
if len((*req).TLS.PeerCertificates) > 0 {
bld.WriteString("- Peer Certificates:
\n\n")
for _, cert := range (*req).TLS.PeerCertificates {
bld.WriteString(fmt.Sprintf("- %v
\n", (*cert).Subject))
}
bld.WriteString("
\n")
}
bld.WriteString("
\n")
bld.WriteString("\n\n")
w.Write([]byte(bld.String()))
}
func main() {
var certfile = flag.String("c", "server.crt","Server Certificate Path")
var keyfile = flag.String("k", "server.key", "Server Key Path")
var port = flag.Int("p", 443, "Port number")
var minver = flag.String("m", "TLS10", "Min TLS Version [TLS10/11/12/13]")
var maxver = flag.String("M", "TLS13", "Max TLS Version [TLS10/11/12/13]")
var authtype = flag.String("A", "NONE",
"Client auth type [NONE/WANT/NEED/WANTVFY/NEEDVFY]")
log.SetFlags(log.Ldate | log.Ltime)
flag.Parse()
log.Printf("Port: %d\n", *port)
log.Printf("Cert File: %s\n", *certfile)
log.Printf("Key File: %s\n", *keyfile)
// Set up the TLS configuration and allow the client to control min/max
// protocol versions and client authentication behavior.
config := &tls.Config {
MinVersion: uint16(versions[strings.ToUpper(*minver)]),
MaxVersion: uint16(versions[strings.ToUpper(*maxver)]),
ClientAuth: authopts[strings.ToUpper(*authtype)],
}
// Set up the HTTP server using the above TLS configuration information
http.HandleFunc("/", createResponse)
serv := &http.Server {
Addr: ":" + strconv.Itoa(*port),
TLSConfig: config,
}
err := serv.ListenAndServeTLS(*certfile, *keyfile)
if err != nil {
log.Println(err)
return
}
}